Назад | Перейти на главную страницу

Как вывести определенные строки из текстового файла в Linux?

Думаю, всем известны полезные линейные утилиты Linux cmd head и tail. head позволяет распечатать первые X строк файла, tail делает то же самое, но печатает конец файла. Какая хорошая команда для печати середины файла? что-то вроде middle --start 10000000 --count 20 (выведите строки с 10'000 по 10'000'010).

Я ищу то, что будет эффективно работать с большими файлами. Я попытался tail -n 10000000 | head 10 и это ужасно медленно.

sed -n '10000000,10000020p' filename

Вы могли бы немного ускорить это следующим образом:

sed -n '10000000,10000020p; 10000021q' filename

В этих командах опция -n причины sed для «подавления автоматической печати пространства шаблона». В p команда "распечатать [s] текущее пространство шаблонов" и q команда «Немедленно закрыть [s] сценарий sed без дополнительной обработки ввода ...» Цитаты взяты из sed man страница.

Кстати, ваша команда

tail -n 10000000 filename | head 10

начинается с десятимиллионной строки от конец файла, в то время как ваша "средняя" команда, похоже, начинается с десятимиллионной от начало что было бы эквивалентно:

head -n 10000010 filename | tail 10

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

Однако если файл отсортирован (например, файл журнала с отметками времени) или имеет строки фиксированной длины, то вы можете искать в файле на основе позиции байта. В примере с файлом журнала вы можете выполнять двоичный поиск несколько раз, как мой скрипт Python Вот* делает. В случае файла с фиксированной длиной записи это действительно просто. Ты просто ищешь linelength * linecount символов в файл.

* Я все еще хочу опубликовать еще одно обновление для этого скрипта. Может быть, я найду это на днях.

Я обнаружил следующее использование sed

sed -n '10000000,+20p'  filename

Надеюсь, это кому-нибудь пригодится!

Это мой первый пост здесь! Во всяком случае, это просто. Допустим, вы хотите извлечь строку 8872 из файла с именем file.txt. Вот как это сделать:

cat -n file.txt | grep '^ * 8872'

Теперь вопрос в том, чтобы найти после этого 20 строк. Для этого вы делаете

cat -n file.txt | grep -A 20 '^ * 8872'

Чтобы увидеть строки вокруг или перед ними, смотрите флаги -B и -C в руководстве по grep.

Ответ Денниса - правильный путь. Но используя только голову и хвост под bash:

middle () { head -n $[ $1 + $2 ] | tail -n $2; }

Это дважды сканирует первые строки $ 1 + $ 2, что намного хуже, чем ответ Денниса. Но вам не нужно запоминать все эти буквы sed, чтобы использовать его ...

Используйте следующую команду, чтобы получить конкретный диапазон строк

awk 'NR < 1220974{next}1;NR==1513793{exit}' debug.log | tee -a test.log

Здесь debug.log - это мой файл, в котором отсутствуют строки, и я использовал для вывода строк с номера строки 1220974 на 1513793 в файл test.log. надеюсь, что это будет полезно для захвата диапазона строк.

Рубиновая одинарная версия.

ruby -pe 'next unless $. > 10000000 && $. < 10000020' < filename.txt

Может кому-нибудь пригодится. Решения с «sed», предоставленные Деннисом и Доксом, очень хороши, даже потому, что кажутся быстрее.

Вы можете использовать "nl".

nl filename | grep <line_num>

Например, этот awk будет печатать строки от 20 до 40

awk '{if ((NR> 20) && (NR <40)) print $ 0}' / etc / passwd

Если вы знаете номера строк, скажем, вы хотите получить строки 1, 3 и 5 из файла, скажем, / etc / passwd:

perl -e 'while(<>){if(++$l~~[1,3,5]){print}}' < /etc/passwd

Perl - король:

perl -ne 'print if ($. == 10000000 .. $. == 10000020)' filename