Wie kann der Zeilenzähler für das Ersetzen des Zeilenbeginns durch AWK /… erhöht werden?


9

Ich habe zuerst über SED ( sed "s/^/COUNTER \&/" /tmp/1.tex) nachgedacht, aber es ist für eine einzelne Zeile konzipiert, und ich kann den Zähler selbst nicht erhöhen, indem awkich jetzt so nachdenke, weil ich großartige Erfahrungen mit gawkintegrierten Ansätzen habe. Daten

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

Erwartete Ausgabe

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

Betriebssystem: Debian 8.5

Antworten:


11

nl ist ein Dienstprogramm zum Nummerieren der Zeilen einer Datei. Verwendung:

nl /path/to/file

In Ihrem speziellen Fall:

$ 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

Wie können Sie dies mit dem vorangestellten Zähler und dem kaufmännischen Und kombinieren? - - Es funktioniert für den Zähler, ist sich aber nicht sicher, ob es auch für letzteren gilt.
Léo Léopold Hertz 준영

3
nl -s ' &' /path/to/file. -sGibt an, was die Zahlen vom Hauptteil der Eingabedatei trennt.
DopeGhoti

1
nlunterscheidet sich von cat -nund die awkLösung darin, dass es standardmäßig keine leeren Zeilen
nummeriert

10

Dies erreicht das, wonach Sie suchen. (wie auch awk '$0=NR" & "$0' filename, aber das ist ein bisschen kryptisch)

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

Oder wenn sedvorzuziehen, ergibt dies das gleiche Ergebnis.

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

perl Ansätze.

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

Wie haben Sie diese Syntax gefunden sed = filename | ...? - - Ich wusste nicht, dass Sie sed mit equalSymbol verwenden können. - - Kann Ihre sedAussage in dynamischen Umgebungen funktionieren? Irgendwelche Schwächen?
Léo Léopold Hertz 준영

1
@ LéoLéopoldHertz 준영 Ich ​​habe unter Manpage nachgesehen, der =Operator befindet sich im Abschnitt "Null- oder Einadressenbefehle".
Sergiy Kolodyazhnyy

Ja = Print the current line number. Die Funktion ist also tatsächlich in sed integriert. Nett!
Léo Léopold Hertz 준영

3

Python kann hierfür eine gute Alternative sein:

$ 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

Dies funktioniert so, dass wir Text in Pythons Standard umleiten und von dort aus Zeilen lesen. enumerate()Funktion gibt die Zeilenanzahl an, wobei sys.stdinals Eingabe angegeben und 1der Startindex ist. Der Rest ist einfach: Wir erstellen eine Liste neuer Zeichenfolgen, indem wir den Index als Zeichenfolge zusammenfügen, die mit der ' & 'Zeichenfolge und der Zeile selbst verbunden ist. Schließlich wird alles, was von der ''.join()Funktion aus der Liste zu einem Test zusammengesetzt wird .

Alternativ ist hier eine mehrzeilige Version für eine Skriptdatei oder einfach zur besseren Lesbarkeit:

#!/usr/bin/env python
import sys

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

Funktioniert trotzdem:

$ ./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

Aber wenn Sie es lieber in Bash machen, dann können Sie das auch machen:

$ 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 준영 Wenn ich das ohne Aufzählung machen würde, würde ich eine Variable benötigen, die die Anzahl der Zeilen verfolgt, und ich muss diese Variable initiieren und jedes Mal erhöhen. Die Verwendung enumerate()spart wie 3 Codezeilen. Dies ist nützlich, wenn Sie sich mit anderen Dingen befassen, z. B. der Verarbeitung von Elementen in Listen. Siehe docs.python.org/2/library/functions.html#enumerate
Sergiy Kolodyazhnyy

@ LéoLéopoldHertz 준영 Wenn Sie die Verwendung von Zählern wie im bashBeispiel verstehen, können Sie diese gerne verwenden :) Ich habe aus Erfahrung festgestellt enumerate(), dass sie eleganter ist, aber das ist nur meine Meinung. Verwenden Sie auf jeden Fall eine andere Methode, wenn Sie der Meinung sind, dass dies klarer ist
Sergiy Kolodyazhnyy

OK, enumerateist klarer als die variable Instanziierung. Kann der Lambda-Ausdruck Platz sparen?
Léo Léopold Hertz 준영

@ LéoLéopoldHertz 준영 Es könnte Platz in einem langen Skript sparen, aber in diesem Fall sehe ich einfach nicht, wie das helfen könnte.
Sergiy Kolodyazhnyy

2

Dies ist auch eine Option cat -nmit automatischer Nummerierung:

while read num line;do echo $num "&" $line;done <<<$(cat -n a.txt)
Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.