Come incrementare il contatore di linea per le sostituzioni di inizio linea di AWK / ...?


9

Ho pensato per la prima volta a SED ( sed "s/^/COUNTER \&/" /tmp/1.tex) ma è progettato per una singola linea e non posso incrementare il contatore stesso pensando così ora awkperché ho grandi esperienze con gawkapprocci integrati. Dati

What & South Dragon & North Dragon    & 5 \\ \hline
What & South Dragon & North Dragon    & 5 \\ \hline
What & South Dragon & North Dragon    & 5 \\ \hline

Uscita prevista

1 & What & South Dragon & North Dragon    & 5 \\ \hline
2 & What & South Dragon & North Dragon    & 5 \\ \hline
3 & What & South Dragon & North Dragon    & 5 \\ \hline

Sistema operativo: Debian 8.5

Risposte:


11

nl è un'utilità per numerare le righe di un file.

nl /path/to/file

Nel tuo caso specifico:

$ nl  -s ' & ' input.txt                                                                                                 
     1 & What & South Dragon & North Dragon    & 5 \\ \hline
     2 & What & South Dragon & North Dragon    & 5 \\ \hline
     3 & What & South Dragon & North Dragon    & 5 \\ \hline

Come si può combinare questo con contatore preappending e la e commerciale? - - Funziona per il contatore, ma non è sicuro se anche per quest'ultimo.
Léo Léopold Hertz

3
nl -s ' &' /path/to/file. -sspecifica cosa separa i numeri dal corpo del file di input.
DopeGhoti,

1
nldifferisce da cat -ne la awksoluzione in quanto non
numera

10

Questo raggiunge ciò che stai cercando. (come fa awk '$0=NR" & "$0' filename, ma è un po 'enigmatico)

awk '{print NR,"&",$0}' filename
1 & What & South Dragon & North Dragon    & 5 \\ \hline
2 & What & South Dragon & North Dragon    & 5 \\ \hline
3 & What & South Dragon & North Dragon    & 5 \\ \hline

O se sedpreferibile, questo dà lo stesso risultato.

sed = filename | sed 'N;s/\n/ \& /'

perl approcci.

perl -pe '$_="$. & $_"' filename
perl -pe 's/^/$. & /' filename

Come hai trovato questa sintassi sed = filename | ...? - - Non sapevo che puoi usare sed con il equalsimbolo. - - La tua seddichiarazione può funzionare in ambienti dinamici? Qualche debolezza?
Léo Léopold Hertz

1
@ LéoLéopoldHertz 준영 Ho guardato nella pagina man, l' =operatore è nella sezione "Comandi a indirizzo zero o uno".
Sergiy Kolodyazhnyy,

Sì, = Print the current line number. Quindi la funzione è effettivamente integrata in sed. Bello!
Léo Léopold Hertz

3

Python può essere un buon strumento alternativo per questo:

$ python -c "import sys;lines=[str(i)+' & '+l for i,l in enumerate(sys.stdin,1)]; print ''.join(lines)" < input.txt      
1 & What & South Dragon & North Dragon    & 5 \\ \hline
2 & What & South Dragon & North Dragon    & 5 \\ \hline
3 & What & South Dragon & North Dragon    & 5 \\ \hline

Il modo in cui funziona è che reindirizziamo il testo nello stdin di Python e leggiamo le righe da lì. enumerate()La funzione è ciò che dà il conteggio delle righe, con sys.stdinspecificato come input ed 1è l'indice iniziale. Il resto è semplice: creiamo un elenco di nuove stringhe eseguendo il casting dell'indice come stringa unita insieme a ' & 'stringa e alla riga stessa. Infine, tutto ciò che viene riassemblato dall'elenco in un test dalla ''.join()funzione.

In alternativa, ecco una versione multilinea per un file di script o semplicemente per leggibilità:

#!/usr/bin/env python
import sys

for index,line in enumerate(sys.stdin,1):
    print str(index) + ' & ' + line.strip()

Funziona allo stesso modo:

$ ./line_counter.py  < input.txt                                                                                         
1 & What & South Dragon & North Dragon    & 5 \\ \hline
2 & What & South Dragon & North Dragon    & 5 \\ \hline
3 & What & South Dragon & North Dragon    & 5 \\ \hline

Ma se preferisci farlo in bash, anche quello può essere fatto:

$ counter=1; while read line ; do printf "%s & %s\n" "$counter" "$line" ; counter=$(($counter+1)) ; done < input.txt
1 & What & South Dragon & North Dragon    & 5 \ hline
2 & What & South Dragon & North Dragon    & 5 \ hline
3 & What & South Dragon & North Dragon    & 5 \ hline

1
@ LéoLéopoldHertz 준영 Beh, se dovessi farlo senza enumerare, avrei bisogno di una variabile che tiene traccia del numero di righe, e dovrei iniziare quella variabile e incrementare ogni volta. Usando si enumerate()salva come 3 righe di codice. È utile quando si tratta di altre cose, come l'elaborazione di elementi negli elenchi. Vedi docs.python.org/2/library/functions.html#enumerate
Sergiy Kolodyazhnyy

@ LéoLéopoldHertz 준영 se capisci l'uso del contatore come faccio io bashnell'esempio, allora sentiti libero di usarlo :) Ho appena scoperto dall'esperienza enumerate()di essere più elegante, ma questa è solo la mia opinione.
Sicuramente

OK, enumerateè più chiaro dell'istanza variabile. L'espressione lambda può risparmiare spazio?
Léo Léopold Hertz

@ LéoLéopoldHertz 준영 Potrebbe risparmiare spazio in una lunga sceneggiatura, ma in questo caso non vedo come possa essere d'aiuto.
Sergiy Kolodyazhnyy,

2

Questa è anche un'opzione che utilizza cat -ncon la numerazione automatica:

while read num line;do echo $num "&" $line;done <<<$(cat -n a.txt)
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.