Jak zwiększyć licznik linii dla zamiany początku linii na AWK /…?


9

Najpierw pomyślałem o SED ( sed "s/^/COUNTER \&/" /tmp/1.tex), ale jest on zaprojektowany dla pojedynczej linii i nie mogę zwiększyć licznika przez sed tak myśląc teraz, awkponieważ mam świetne doświadczenia ze gawkzintegrowanymi podejściami. Dane

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

Oczekiwany wynik

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

System operacyjny: Debian 8.5

Odpowiedzi:


11

nl to narzędzie do numerowania linii pliku.

nl /path/to/file

W twoim konkretnym przypadku:

$ 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

Jak można to połączyć z licznikiem i aplikacją? - - Działa dla licznika, ale nie jestem pewien, czy również dla tego ostatniego.
— Léo Léopold Hertz -

3
nl -s ' &' /path/to/file. -sokreśla, co oddziela liczby od treści pliku wejściowego.
— DopeGhoti

1
nlróżni się od cat -ni awkrozwiązanie w tym, że nie liczba pustych linii domyślnie
— Iruvar

10

To osiąga to, czego szukasz. (jak robi awk '$0=NR" & "$0' filename, ale to trochę tajemnicze)

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

Lub jeśli jest to sedpreferowane, daje to ten sam rezultat.

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

perl podejścia.

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

Jak znalazłeś tę składnię sed = filename | ...? - - Nie wiedziałem, że możesz używać sed z equalsymbolem. - - Czy twoje sedoświadczenie może działać w dynamicznych środowiskach? Jakieś słabości?
— Léo Léopold Hertz -

1
@ LéoLéopoldHertz looked Zajrzałem do strony podręcznika użytkownika, =operator znajduje się w sekcji „Polecenia zera lub jeden adres”.
— Sergiy Kolodyazhnyy

Tak = Print the current line number. Tak więc funkcja jest faktycznie wbudowana w sed. Miły!
— Léo Léopold Hertz -

3

Python może być dobrym alternatywnym narzędziem do tego:

$ 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

Działa to tak, że przekierowujemy tekst do standardowego interfejsu Pythona i odczytujemy stamtąd wiersze. enumerate()funkcja podaje liczbę wierszy, sys.stdinpodana jako dane wejściowe i 1jest indeksem początkowym. Reszta jest prosta - tworzymy listę nowych ciągów, rzutując indeks jako ciąg połączony razem z ' & 'ciągiem i samą linią. Wreszcie, wszystko to jest ponownie składane z listy w jeden test przez ''.join()funkcję.

Alternatywnie, oto wieloliniowa wersja pliku skryptu lub po prostu dla czytelności:

#!/usr/bin/env python
import sys

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

Działa tak samo:

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

Ale jeśli wolisz robić to w bashu, możesz to również zrobić:

$ 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 준영 Cóż, gdybym zrobił to bez wyliczenia, potrzebowałbym zmiennej, która śledzi liczbę linii, i muszę ją inicjować i za każdym razem zwiększać. Używanie enumerate()oszczędza jak 3 linie kodu. Jest to przydatne, gdy mamy do czynienia z innymi rzeczami, takimi jak przetwarzanie pozycji na listach. Zobacz docs.python.org/2/library/functions.html#enumerate
— Sergiy Kolodyazhnyy

@ LéoLéopoldHertz 준영 jeśli rozumiesz używanie licznika tak jak ja na bashprzykład, to skorzystaj z niego :) Właśnie z doświadczenia zauważyłem, enumerate()że jest bardziej elegancki, ale to tylko moja opinia.
— Oczywiście

OK, enumeratejest bardziej przejrzysty niż tworzenie instancji zmiennej. Czy wyrażenie lambda może zaoszczędzić trochę miejsca?
— Léo Léopold Hertz 준영

@ LéoLéopoldHertz 준영 To może zaoszczędzić miejsce w długim skrypcie, ale w tym przypadku po prostu nie widzę, jak to może pomóc.
— Sergiy Kolodyazhnyy

2

Jest to również opcja korzystająca cat -nz automatycznego numerowania:

while read num line;do echo $num "&" $line;done <<<$(cat -n a.txt)
Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.