Як збільшити лічильник ліній для заміни початку рядка на AWK /…?


9

Я спершу подумав про SED ( sed "s/^/COUNTER \&/" /tmp/1.tex), але він розроблений для однієї лінії, і я не можу збільшити лічильник на sed так, що думаю зараз, awkтому що у мене великий досвід роботи з gawkінтегрованими підходами. Дані

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

Очікуваний вихід

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

ОС: Debian 8.5

Відповіді:


11

nl це утиліта для нумерації рядків файлу. Використання:

nl /path/to/file

У вашому конкретному випадку:

$ 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

Як ви можете поєднати це з попередньою лічильником та амперсандом? - - Він працює для лічильника, але не впевнений, чи для останнього.
Лео Леопольд Герц 준영

3
nl -s ' &' /path/to/file. -sвказує, що відокремлює числа від тіла вхідного файлу.
DopeGhoti

1
nlРішення відрізняється від cat -nта awkрішення тим, що за замовчуванням не
нумерує

10

Це дозволяє досягти того, що ви хочете. (як це робиться awk '$0=NR" & "$0' filename, але це трохи криво)

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

Або, якщо sedкраще, це дає такий же результат.

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

perl підходи.

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

Як ви знайшли цей синтаксис sed = filename | ...? - - Я не знав, що ти можеш використовувати sed із equalсимволом. - - Чи може ваша sedзаява працювати в динамічних умовах? Якісь слабкі місця?
Лео Леопольд Герц 준영

1
@ LéoLéopoldHertz 준영 Я переглянув сторінку man, =оператор знаходиться в розділі "Нульові або одноадресні команди".
Сергій Колодяжний

Так, = Print the current line number. Тож функція насправді вбудована в sed. Приємно!
Лео Леопольд Герц 준영

3

Python може бути хорошим альтернативним інструментом для цього:

$ 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

Як це працює, ми перенаправляємо текст у stdin python і звідти читаємо рядки. enumerate()Функція - це те, що дає кількість рядків, sys.stdinвказане як вхідне і 1є початковим індексом. Решта просте - ми складаємо список нових рядків, переводячи індекс, як рядок, з'єднаний разом із ' & 'рядком, так і сам рядок. Нарешті, все, що збирається зі списку в один тест ''.join()функцією.

Крім того, ось багатолінійна версія для файлу сценарію або просто для читання:

#!/usr/bin/env python
import sys

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

Працює точно так само:

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

Але якщо ви віддаєте перевагу робити це в bash, то це також можна зробити:

$ 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 준영 Ну, якби я зробив це без перерахунку, мені знадобиться змінна, яка відстежує кількість рядків, і мені потрібно ініціювати цю змінну та збільшення кожного разу. Використання enumerate()зберігає, як 3 рядки коду. Це корисно при роботі з іншими речами, як-от обробка предметів у списках. Дивіться docs.python.org/2/library/functions.html#enumerate
Сергій Колодяжний

@ LéoLéopoldHertz 준영 якщо ви розумієте, що використовуєте лічильник, як я, bashнаприклад, тоді сміливо використовуйте це :) Я просто виявив, що досвід enumerate()є більш елегантним, але це лише моя думка. У будь-якому випадку використовуйте інший метод, якщо ви вважаєте, що це зрозуміліше
Сергій Колодяжний

Гаразд, enumerateзрозуміліше, ніж змінна інстанція. Чи може лямбдаський вираз заощадити трохи місця?
Лео Леопольд Герц 준영

@ LéoLéopoldHertz 준영 Це може заощадити місце в довгому сценарії, але в цьому випадку я просто не бачу, як це могло б допомогти.
Сергій Колодяжний

2

Це також варіант використання cat -nз автоматичною нумерацією:

while read num line;do echo $num "&" $line;done <<<$(cat -n a.txt)
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.