Come stampare la prima colonna della riga successiva nella riga corrente?


8

Ho alcuni file come questo:

abc 123    
abc 789  
bcd 456  
acb 135

Vorrei stampare la prima colonna della riga successiva nella riga corrente.

Uscita desiderata:

abc  123 abc  
abc 789 bcd  
bcd 456 acb  
acb 135 

Preferisco usare awk.

Risposte:


16

Memorizza la riga precedente:

awk 'NR > 1 { print prev, $1 } { prev = $0 } END { print prev }'

Questo elabora l'input come segue:

  • se la riga corrente è la seconda o maggiore, stampare la riga precedente (memorizzata in prev, vedere il passaggio successivo) e il primo campo della riga corrente, separati dal separatore del campo di output (il carattere spazio per impostazione predefinita);
  • in tutti i casi, memorizzare la riga corrente nella prevvariabile;
  • alla fine del file, stampa la riga precedente.

11

awkApproccio alternativo :

$ awk 'NR == 1{printf "%s", $0;next}{printf " %s\n%s", $1,$0}' input.txt                                    
abc 123 abc
abc 789 bcd
bcd 456 acb
acb 135

Il modo in cui funziona è semplice: la prima riga è un caso speciale: lo stampiamo senza nuova riga e diciamo a awk di passare alla riga successiva senza eseguire altri blocchi di codice. Successivamente, NR == 1{printf "%s", $0;next}viene saltato, ma altre parti fanno il lavoro.

Ricorda che fino ad ora abbiamo stampato una stringa formattata senza un nuovo carattere di riga. Pertanto, ciò che viene fatto printf " %s\n%s",$1,$0ora è la prima parola che viene stampata (e poiché non c'era una nuova riga, rimane sulla stessa riga di output), la nuova riga inserita e quindi l'intera riga stessa (ma non termina con il carattere di nuova riga) . Quindi la prima parola successiva inserita rimarrà sulla stessa riga. Il processo continua fino a quando non raggiungiamo la fine del file.

Il possibile miglioramento è includere il END{print ""}blocco per inserire la nuova riga finale. In alcuni casi in cui il file risultante deve essere elaborato da altri script potrebbe essere desiderabile.


Mentre l'utente ha richiesto AWK in modo specifico, lo stesso approccio con la stampa di stringhe formattate può essere adottato con altre lingue, ad esempio Python. L'alternativa Python ha fornito a coloro che erano curiosi di sapere come implementarlo in altre lingue:

#!/usr/bin/env python
from __future__ import print_function
import sys

old = None
for index,line in enumerate(sys.stdin):
    if index == 0:
        print(line.strip(),end=" ")
        continue
    words = line.strip().split()
    print(words[0] + "\n" + line.strip(),end=" ")

E l'utilizzo in questo modo:

$ ./append_first.py < input.txt                            
abc 123 abc
abc 789 bcd
bcd 456 acb
acb 135

La stessa idea sulla newline finale si applica qui.


9

Ecco un brutto sedmodo solo per divertimento

sed '2,$ s/[^ ]\+/& &/; 2,$ s/ /\n/' file | paste -d ' ' - -
abc 123 abc
abc 789 bcd
bcd 456 acb
acb 135 

Spiegazione

  • 2,$ dalla seconda riga all'ultima
  • s/[^ ]\+/& &/ raddoppia il primo set di caratteri non bianchi
  • ; separa i comandi, come nella shell
  • s/ /\n/ sostituire il primo spazio con una nuova riga
  • paste -d ' ' - - incollare questo pasticcio insieme (aggiungi la seconda riga alla terza, la quarta riga alla terza, ecc.)

1
In alternativa puoi usarlo sedda solo senza paste:sed -r 'N;s/\n(\w+)/\1&/;P;D' somefile.txt
Trauma digitale

1
Se scrivi sedprogrammi per divertimento, allora forse dovresti provare Code-golf ;-)
Digital Trauma

1
@DigitalTrauma è stata sul campo da golf già da 2 mesi;)
Sergiy Kolodyazhnyy

1

Secondo me l'approccio più semplice e più leggibile è:

  1. estrarre la prima colonna ( cut)
  2. elimina la prima riga dalla colonna estratta ( tail)
  3. incolla questa colonna nel tuo file sorgente ( paste)

Esempio: il tuo file inpult di esempio:

abc 123    
abc 789  
bcd 456  
acb 135

Quindi eseguire il comando seguente in un terminale

cut -d' ' -f1 in.txt | tail -n +2 | paste -d' ' file -

Produzione:

abc 123 abc
abc 789 bcd
bcd 456 acb
acb 135

La struttura alla base di questa soluzione differisce dalle risposte fornite. Non sono necessarie condizioni, cicli o espressioni regolari.

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.