Как увеличить счетчик строк для замены начала строки на 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
DopeGhoti
источник
Как вы можете совместить это с предварительно появившимся счетчиком и амперсандом? - Это работает для счетчика, но не уверен, что и для последнего.
Лео Леопольд Герц 준영
3
nl -s ' &' /path/to/file, -sуказывает, что отделяет числа от тела входного файла.
DopeGhoti
1
nlотличается от cat -nи awkрешение в том , что это не число пустых строк по умолчанию
Iruvar
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 준영 Я посмотрел в справочной странице, =оператор находится в разделе «Команды нулевого или одноадресного ».
Сергей Колодяжный
Да, = 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

Это работает так, что мы перенаправляем текст в стандартный поток 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)
Георгий Васильев
источник