Как увеличить счетчик строк для замены начала строки на 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решение в том , что это не число пустых строк по умолчанию
— 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 준영 Это может сэкономить место в длинном сценарии, но в этом случае я просто не понимаю, как это могло бы помочь.
— Сергей Колодяжный

Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.