Пользовательский номер строки/префикс для текстового файла с использованием awk/sed

Прежде чем поднять флаг, я попробовал несколько вещей, но не получил желаемого результата.

У меня есть много текстовых файлов, к которым я хочу добавить собственную нумерацию;

   the first 2 lines should be prefixed  00A:  , 00B:  
   and remaining lines should be incremental, like 001:  ,002:  ,003:  , and so on

В настоящее время я использую эту команду для возрастающей нумерации.

awk '{printf("%03d:  %s\r\n", NR,$0)}' file1.txt > file2.txt

*который делает дополнительные номера. ок для всего файла; но не несколько необходимых типов.

Пример входного файла:

136725A6449C5279 933FB466C9CD699B
8FFBBA87E9D3209A AB41FBDC5E281A92
FF80DA7B0054FB29 006BF1C82C75C341
FA118264221B02A7 81E9A1FEB75FFB3D
31AA9FC566C3ADE0 70DDFD6DED2BF29C
F0B39014DA7FA6B1 77401108A81E33E1
74EF54060BC2B72F B5518D896DDC266F
DE10C97F9FBDA5A6 6C79566CA1BDC06E

Желаемый результат:

00A:  136725A6449C5279 933FB466C9CD699B
00B:  8FFBBA87E9D3209A AB41FBDC5E281A92
001:  FA118264221B02A7 81E9A1FEB75FFB3D
002:  31AA9FC566C3ADE0 70DDFD6DED2BF29C
003:  F0B39014DA7FA6B1 77401108A81E33E1
004:  74EF54060BC2B72F B5518D896DDC266F
005:  DE10C97F9FBDA5A6 6C79566CA1BDC06E

🤔 А знаете ли вы, что...
Shell обеспечивает множество утилит для обработки текста, таких как awk, sed и grep.


1
50
4

Ответы:

Решено

Ни Awk, ни sed не делают этого хорошо, но в Perl это встроено.

perl -pe 'BEGIN { $prefix = "A"; }
  $prefix = "1" if ($. == 3);
  printf "%03s:  ", $prefix++;' file

Важнейшей особенностью здесь является то, что в Perl "A"++ производит "B" изначально. Однако с ведущими нулями это работает не так хорошо; поэтому я прибегнул к дополнению здесь.

Ваш вопрос довольно неясен относительно того, что должно произойти после 00Z или после 009, поэтому мне пришлось гадать. В Perl "Z"++ есть "AA".

Если вы действительно настаиваете на решении Awk, это можно сделать примерно так:

awk '{ printf("%03s:  %s\n", (NR == 1 ? "A" : \
    (NR == 2 ? "B" : NR-2)), $0)}' file

Я вынул фугли \r; если вы используете Windows, возможно, верните его обратно (или рассмотрите свои варианты).

Как отмечено в комментариях, это работает на MacOS / nawk, но может не работать на других Awk.


С любым POSIX awk:

awk '{s = NR>2 ? sprintf("%03d",NR-2) : "00" substr("AB",NR,1); print s ":  " $0}'

Я бы использовал GNU AWK для этой задачи следующим образом: пусть file.txt контент будет

Able
Baker
Charlie
Dog

затем

awk -v prefixes = "00A 00B" 'BEGIN{split(prefixes,arr)}{prefix=(NR in arr)?arr[NR]:sprintf("%03d",++i);print prefix ":  " $0}' file.txt

дает результат

00A:  Able
00B:  Baker
001:  Charlie
002:  Dog

Объяснение: я устанавливаю переменную prefixes в список префиксов с разделением пробелов, затем в начале заполняю массив arr в контексте. Для каждой строки я проверяю, есть ли в массиве префикс для данной строки, если да, то я использую их, в противном случае я использую sprintf для создания префикса из предварительно увеличенной переменной i, затем печатаю конкатенацию префикса, желаемого разделителя и заданной строки. Это решение автоматически адаптируется к любому количеству префиксов, например. если вы хотите 00A 00B 00C, то достаточно установить префиксы 00A 00B 00C.

(проверено в GNU Awk 5.1.0)


Используя любой awk:

$ awk -v OFS=':  ' '{print ( NR<3 ? sprintf("00%c",NR+64) : sprintf("%03d",NR-2) ), $0}' file
00A:  136725A6449C5279 933FB466C9CD699B
00B:  8FFBBA87E9D3209A AB41FBDC5E281A92
001:  FF80DA7B0054FB29 006BF1C82C75C341
002:  FA118264221B02A7 81E9A1FEB75FFB3D
003:  31AA9FC566C3ADE0 70DDFD6DED2BF29C
004:  F0B39014DA7FA6B1 77401108A81E33E1
005:  74EF54060BC2B72F B5518D896DDC266F
006:  DE10C97F9FBDA5A6 6C79566CA1BDC06E