А если вам по какой-то причине нужно использовать трубы, то вот так:
cat file.txt |(head; tail)
Примечание: будет печатать повторяющиеся строки, если количество строк в файле file.txt меньше, чем строки заголовка по умолчанию + строки хвоста по умолчанию.
Строго говоря, это не дает вам хвоста исходного файла, но хвост потока после того, headкак потребляет первые 10 строк файла. (Сравните это с head < file.txt; tail < file.txtфайлом, в котором меньше 20 строк). Это очень незначительный момент, о котором нужно помнить. (Но все же +1.)
Чепнер
15
Ницца. Если вам нужен промежуток между головой и хвостом: (голова; эхо; хвост) <file.txt
@nametal На самом деле, вы можете и не получить столько. Хотя отображаютсяhead только первые 10 строк своего ввода, нет гарантии, что он не потреблял его больше, чтобы найти окончание 10-й строки, оставляя для отображения меньшую часть ввода . less
chepner
20
К сожалению, ответ работает только в некоторых случаях. seq 100 | (head; tail)дает мне только первые 10 чисел. Только при гораздо большем размере ввода (например seq 2000) хвост получает некоторый ввод.
Что делать, если в файле больше или меньше 200 строк? А вы не знаете количество строк ab initio?
Пол
@Paul Я изменил sedкed
к
14
Для чистого потока (например, вывода из команды) вы можете использовать «tee», чтобы разветвлять поток и отправлять один поток в начало и один в хвост. Для этого необходимо использовать функцию '> (list)' в bash (+ / dev / fd / N):
( COMMAND | tee /dev/fd/3| head )3>>( tail )
или используя / dev / fd / N (или / dev / stderr) плюс подоболочки со сложным перенаправлением:
(( seq 1100| tee /dev/fd/2| head 1>&3)2>&1| tail )3>&1(( seq 1100| tee /dev/stderr | head 1>&3)2>&1| tail )3>&1
(Ни один из них не будет работать в csh или tcsh.)
Для чего-то с немного лучшим контролем вы можете использовать эту команду perl:
COMMAND | perl -e 'my $size = 10; my @buf = (); while (<>) { print if $. <= $size; push(@buf, $_); if ( @buf > $size ) { shift(@buf); } } print "------\n"; print @buf;'
+1 за поддержку потока. Вы можете повторно использовать stderr:COMMAND | { tee >(head >&2) | tail; } |& other_commands
jfs
2
кстати, он ломается для файлов, размер которых превышает размер буфера (8K в моей системе). cat >/dev/nullисправляет:COMMAND | { tee >(head >&2; cat >/dev/null) | tail; } |& other_commands
jfs
Я любил решение, но после игры на аа , а я не заметил , что в некоторых случаях хвост работает до головы ... там не гарантируется порядок между headи tailкомандами: \ ...
Jan
7
(sed -u 10q; echo ...; tail)< file.txt
Еще один вариант (head;tail)темы, но без проблемы с начальным заполнением буфера для небольших файлов.
Хорошо, я всегда использовал catи / headили tailтрубку, приятно знать, что я могу использовать их индивидуально!
Пол
Как я могу передать эти первые 10 + последние 10 в другую команду?
топ
1
@Paul - с 'your_program' как wc -l он возвращает 10 вместо 20
вершина
3
или без необходимости порождать подоболочку: { head file; tail file; } | prog(требуется
пробел
1
Ничего себе ... голосование "против" за ответ, очень похожий на ответы других (но с указанием времени до них) спустя почти два года, от человека, который предпочел не публиковать, почему они проголосовали против. Ницца!
проблема здесь в том, что потоковые программы не знают заранее длину файла (потому что его может и не быть, если это настоящий поток).
такие инструменты, как tailбуферизация последних n видимых строк и ожидание конца потока, а затем печать.
если вы хотите сделать это одной командой (и заставить ее работать с любым смещением и не повторять строки, если они перекрываются), вам придется подражать этому поведению, о котором я упоминал.
попробуйте этот awk:
awk -v offset=10'{ if (NR <= offset) print; else { a[NR] = $0; delete a[NR-offset] } } END { for (i=NR-offset+1; i<=NR; i++) print a[i] }' yourfile
Я давно искал это решение. Сам пробовал с sed, но проблема с незнанием длины файла / потока заранее была непреодолимой. Из всех доступных выше вариантов мне нравится awk-решение Camille Goudeseune. Он сделал заметку, что его решение оставило лишние пустые строки в выводе с достаточно небольшим набором данных. Здесь я предлагаю модификацию его решения, убирающую лишние строки.
headtail(){ awk -v offset="$1"'{ if (NR <= offset) print; else { a[NR] = $0; delete a[NR-offset] } } END { a_count=0; for (i in a) {a_count++}; for (i=NR-a_count+1; i<=NR; i++) print a[i] }';}
Что ж, вы всегда можете связать их вместе. Вроде так
head fiename_foo && tail filename_foo,. Если этого недостаточно, вы можете написать себе функцию bash в своем файле .profile или любом файле входа, который вы используете:
head_and_tail(){
head $1 && tail $1
}
И, потом вызвать его из оболочки командной строки: head_and_tail filename_foo.
Зачем использовать cat, если можно просто вызвать head -10 file.txt?
jstarek
Можете ли вы сделать количество строк переменной, чтобы вызов выглядел примерно так: head_ tail (foo, m, n) - возвращение первых m и последних n строк текста?
ricardo
@ricardo , что предполагает написание Баш скрипт , который принимает 3 арг и передает их tailи headили функции по псевдониму-джеями его.
Это работает для файлов известной длины, но не для файлов, длина которых неизвестна.
Кевин
0
Чтобы обрабатывать каналы (потоки), а также файлы, добавьте это в свой файл .bashrc или .profile:
headtail(){ awk -v offset="$1"'{ if (NR <= offset) print; else { a[NR] = $0; delete a[NR-offset] } } END { for (i=NR-offset+1; i<=NR; i++) print a[i] }';}
Тогда можно не только
headtail 10< file.txt
но также
a.out | headtail 10
(Это по-прежнему добавляет ложные пустые строки, когда длина ввода превышает 10, в отличие от обычного старого a.out | (head; tail). Спасибо, предыдущие ответчики.)
Основываясь на том, что @Samus_ объяснил здесь о том, как работает команда @Aleksandra Zalcman, этот вариант удобен, когда вы не можете быстро определить, где начинается хвост, не считая линий.
Я бы сказал, что в зависимости от размера файла активное чтение его содержимого может быть нежелательным. В этом случае, я думаю, будет достаточно простого сценария оболочки.
Вот как я недавно обработал это для ряда очень больших файлов CSV, которые я анализировал:
$ for file in*.csv;do echo "### ${file}"&& head ${file}&& echo ...&& tail ${file}&& echo;done
Это распечатает первые 10 строк и последние 10 строк каждого файла, а также распечатает имя файла и несколько многоточий до и после.
Для одного большого файла вы можете просто запустить следующее для того же эффекта:
$ head somefile.csv && echo ...&& tail somefile.csv
Ответы:
Вы можете просто:
А если вам по какой-то причине нужно использовать трубы, то вот так:
Примечание: будет печатать повторяющиеся строки, если количество строк в файле file.txt меньше, чем строки заголовка по умолчанию + строки хвоста по умолчанию.
источник
head
как потребляет первые 10 строк файла. (Сравните это сhead < file.txt; tail < file.txt
файлом, в котором меньше 20 строк). Это очень незначительный момент, о котором нужно помнить. (Но все же +1.)head
только первые 10 строк своего ввода, нет гарантии, что он не потреблял его больше, чтобы найти окончание 10-й строки, оставляя для отображения меньшую часть ввода .less
seq 100 | (head; tail)
дает мне только первые 10 чисел. Только при гораздо большем размере ввода (напримерseq 2000
) хвост получает некоторый ввод.ed
этоstandard text editor
источник
sed
кed
Для чистого потока (например, вывода из команды) вы можете использовать «tee», чтобы разветвлять поток и отправлять один поток в начало и один в хвост. Для этого необходимо использовать функцию '> (list)' в bash (+ / dev / fd / N):
или используя / dev / fd / N (или / dev / stderr) плюс подоболочки со сложным перенаправлением:
(Ни один из них не будет работать в csh или tcsh.)
Для чего-то с немного лучшим контролем вы можете использовать эту команду perl:
источник
COMMAND | { tee >(head >&2) | tail; } |& other_commands
cat >/dev/null
исправляет:COMMAND | { tee >(head >&2; cat >/dev/null) | tail; } |& other_commands
head
иtail
командами: \ ...Еще один вариант
(head;tail)
темы, но без проблемы с начальным заполнением буфера для небольших файлов.источник
head -10 file.txt; tail -10 file.txt
Помимо этого, вам нужно будет написать свою собственную программу / сценарий.
источник
cat
и /head
илиtail
трубку, приятно знать, что я могу использовать их индивидуально!{ head file; tail file; } | prog
(требуетсяНа основании комментария Дж. Ф. Себастьяна :
Таким образом, вы можете обрабатывать первую строку и остальные по-разному в одном конвейере, что полезно для работы с данными CSV:
источник
проблема здесь в том, что потоковые программы не знают заранее длину файла (потому что его может и не быть, если это настоящий поток).
такие инструменты, как
tail
буферизация последних n видимых строк и ожидание конца потока, а затем печать.если вы хотите сделать это одной командой (и заставить ее работать с любым смещением и не повторять строки, если они перекрываются), вам придется подражать этому поведению, о котором я упоминал.
попробуйте этот awk:
источник
a.out | awk -v ...
Потребовалось много времени, чтобы получить это решение, которое, кажется, единственное, которое охватывает все варианты использования (пока):
Список возможностей:
источник
Я давно искал это решение. Сам пробовал с sed, но проблема с незнанием длины файла / потока заранее была непреодолимой. Из всех доступных выше вариантов мне нравится awk-решение Camille Goudeseune. Он сделал заметку, что его решение оставило лишние пустые строки в выводе с достаточно небольшим набором данных. Здесь я предлагаю модификацию его решения, убирающую лишние строки.
источник
Что ж, вы всегда можете связать их вместе. Вроде так
head fiename_foo && tail filename_foo
,. Если этого недостаточно, вы можете написать себе функцию bash в своем файле .profile или любом файле входа, который вы используете:И, потом вызвать его из оболочки командной строки:
head_and_tail filename_foo
.источник
Первые 10 строк файла file.ext, затем его последние 10 строк:
cat file.ext | head -10 && cat file.ext | tail -10
Последние 10 строк файла, затем первые 10:
cat file.ext | tail -10 && cat file.ext | head -10
Затем вы можете направить вывод в другое место:
(cat file.ext | head -10 && cat file.ext | tail -10 ) | your_program
источник
tail
иhead
или функции по псевдониму-джеями его.Для этого я написал простое приложение на Python: https://gist.github.com/garyvdm/9970522
Он обрабатывает каналы (потоки), а также файлы.
источник
опираясь на идеи выше (проверено bash и zsh)
но используя псевдоним 'hat' Head and Tails
источник
Почему бы не использовать
sed
для этой задачи?sed -n -e 1,+9p -e 190,+9p textfile.txt
источник
Чтобы обрабатывать каналы (потоки), а также файлы, добавьте это в свой файл .bashrc или .profile:
Тогда можно не только
но также
(Это по-прежнему добавляет ложные пустые строки, когда длина ввода превышает 10, в отличие от обычного старого
a.out | (head; tail)
. Спасибо, предыдущие ответчики.)Примечание:,
headtail 10
нетheadtail -10
.источник
Основываясь на том, что @Samus_ объяснил здесь о том, как работает команда @Aleksandra Zalcman, этот вариант удобен, когда вы не можете быстро определить, где начинается хвост, не считая линий.
Или, если вы начнете работать с чем-то другим, кроме 20 строк, подсчет строк может даже помочь.
источник
Чтобы напечатать первые 10 и последние 10 строк файла, вы можете попробовать следующее:
cat <(head -n10 file.txt) <(tail -n10 file.txt) | less
источник
ПРИМЕЧАНИЕ . Переменная aFile содержит полный путь к файлу .
источник
Я бы сказал, что в зависимости от размера файла активное чтение его содержимого может быть нежелательным. В этом случае, я думаю, будет достаточно простого сценария оболочки.
Вот как я недавно обработал это для ряда очень больших файлов CSV, которые я анализировал:
Это распечатает первые 10 строк и последние 10 строк каждого файла, а также распечатает имя файла и несколько многоточий до и после.
Для одного большого файла вы можете просто запустить следующее для того же эффекта:
источник
Потребляет стандартный ввод, но прост и работает в 99% случаев использования
head_and_tail
пример
источник