Сценарий нумерации строк в файле - PullRequest
2 голосов
/ 08 декабря 2008

Мне нужно найти более быстрый способ для нумерации строк в файле особым образом, используя такие инструменты, как awk и sed. Мне нужно, чтобы первый символ в каждой строке был пронумерован следующим образом: 1,2,3,1,2,3,1,2,3 и т. Д.

Например, если ввод был такой:

line 1
line 2
line 3
line 4
line 5
line 6
line 7

Вывод должен выглядеть так:

1line 1
2line 2
3line 3
1line 4
2line 5
3line 6
1line 7

Вот кусок того, что у меня есть. $ lines - это количество строк в файле данных, разделенное на 3. Поэтому для файла из 21000 строк я обрабатываю этот цикл 7000 раз.

export i=0
while [ $i -le $lines ]
do
    export start=`expr $i \* 3 + 1`
    export end=`expr $start + 2`
    awk NR==$start,NR==$end $1 | awk '{printf("%d%s\n", NR,$0)}' >> data.out
    export i=`expr $i + 1`
done

Как правило, это захватывает 3 строки за раз, нумерует их и добавляет к выходному файлу. Это медленно ... а потом немного! Я не знаю другого, более быстрого способа сделать это ... какие-нибудь мысли?

Ответы [ 8 ]

13 голосов
/ 08 декабря 2008

Попробуйте команду nl.

См. https://linux.die.net/man/1/nl (или другую ссылку на документацию, которая появляется, когда вы используете Google для «man nl», или текстовую версию, которая появляется, когда вы запускаете man nl в приглашении оболочки).

Утилита nl читает строки из именованный файл или стандартный ввод, если аргумент файла опущен, применяется настраиваемый фильтр нумерации строк операция и записывает результат в стандартный вывод.

edit: Нет, это неправильно, мои извинения. Команда nl не имеет возможности перезагружать нумерацию каждые n строк, она имеет опцию перезапуска нумерации только после того, как найдет шаблон. Я сделаю этот ответ ответом вики сообщества, потому что он может помочь кому-то узнать о nl.

9 голосов
/ 08 декабря 2008

Это медленно, потому что вы читаете одни и те же строки снова и снова. Кроме того, вы запускаете процесс awk только для его выключения и запуска другого процесса. Лучше сделать все это одним выстрелом:

awk '{print ((NR-1)%3)+1 $0}' $1 > data.out

Если вы предпочитаете пробел после числа:

awk '{print ((NR-1)%3)+1, $0}' $1 > data.out
2 голосов
/ 22 ноября 2011

Это может работать для вас:

 sed 's/^/1/;n;s/^/2/;n;s/^/3/' input
2 голосов
/ 08 декабря 2008

Perl приходит на ум:

perl -pe '$_ = (($.-1)%3)+1 . $_'

должно работать. Без сомнения, есть эквивалент в awk. В основном, ((line# - 1) MOD 3) + 1.

1 голос
/ 04 января 2009

Вам не нужно оставлять bash для этого:

i=0; while read; do echo "$((i++ % 3 + 1)) $REPLY"; done < input
1 голос
/ 08 декабря 2008

Python

import sys
for count, line in enumerate(sys.stdin):
    stdout.write( "%d%s" % ( 1+(count % 3), line )
1 голос
/ 08 декабря 2008
awk '{printf "%d%s\n", ((NR-1) % 3) + 1, $0;}' "$@"
0 голосов
/ 10 декабря 2008

Это должно решить проблему. $ _ напечатает всю строку.

awk '{print ((NR-1)%3+1) $_}' < input
1line 1
2line 2
3line 3
1line 4
2line 5
3line 6
1line 7

# cat input 
  line 1
  line 2
  line 3
  line 4
  line 5
  line 6
  line 7
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...