Думаю, всем известны полезные линейные утилиты 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