Как я извлекаю строки из файла с помощью их номера строки на Unix?

Используя sed или подобный, как Вы извлекли бы строки из файла? Если бы я хотел строки 1, 5, 1010, 20503 из файла, как я получил бы эти 4 строки?

Что, если у меня есть довольно большое количество строк, я должен извлечь? Если у меня был файл с 100 строками, каждый представляющий номер строки, который я хотел извлечь из другого файла, как я сделаю это?

13
задан Jon Seigel 4 April 2010 в 17:31
поделиться

6 ответов

Что-то вроде "sed -n '1p;5p;1010p;20503p". Для подробностей выполните команду "man sed".

Для вашего второго вопроса я бы преобразовал входной файл в кучу команд sed(1), чтобы распечатать нужные мне строки.

15
ответ дан 1 December 2019 в 22:07
поделиться

Это некрасиво и при некоторых обстоятельствах может превысить пределы длины команды*:

sed -n "$(while read a; do echo "${a}p;"; done < line_num_file)" data_file

Или его намного медленнее, но привлекательнее, и, возможно, более воспитанный, брат:

while read a; do echo "${a}p;"; done < line_num_file | xargs -I{} sed -n \{\} data_file

Вариант:

xargs -a line_num_file -I{} sed -n \{\}p\; data_file

Можно немного ускорить версии xarg, добавив опцию -P с каким-нибудь большим аргументом вроде, скажем, 83 или, может быть, 419 или даже 1177, но 10 кажется таким же хорошим, как и любая другая.

*xargs --show-limits может быть поучительным

1
ответ дан 1 December 2019 в 22:07
поделиться

с awk это так же просто, как:

awk 'NR==1 || NR==5 || NR==1010' "file"
5
ответ дан 1 December 2019 в 22:07
поделиться

@OP, вы можете сделать это проще и эффективнее с awk. так что для вашего первого вопроса

awk 'NR~/^(1|2|5|1010)$/{print}' file

для второго вопроса

awk 'FNR==NR{a[$1];next}(FNR in a){print}' file_with_linenr file
2
ответ дан 1 December 2019 в 22:07
поделиться

Я бы исследовал Perl, так как он имеет возможности regexp sed плюс модель программирования, окружающая его, чтобы позволить вам читать файл строка за строкой, считать строки и извлекать по желанию (в том числе и из файла с номерами строк).

my $row = 1
while (<STDIN>) {
   # capture the line in $_ and check $row against a suitable list.
   $row++;
}
0
ответ дан 1 December 2019 в 22:07
поделиться

В Perl:

perl -ne 'print if $. =~ m/^(1|5|1010|20503)$/' file
0
ответ дан 1 December 2019 в 22:07
поделиться
Другие вопросы по тегам:

Похожие вопросы: