Sebenarnya, ini tidak memberi Anda ekor file asli, tetapi ekor aliran setelah headmengkonsumsi 10 baris pertama file. (Bandingkan ini dengan head < file.txt; tail < file.txtpada file dengan kurang dari 20 baris). Hanya poin yang sangat kecil untuk diingat. (Tapi tetap +1.)
chepner
15
Bagus. Jika Anda ingin celah antara bagian kepala dan ekor: (kepala; gema; ekor) <file.txt
@nametal Sebenarnya, Anda bahkan mungkin tidak mendapatkan sebanyak itu. Meskipun headhanya menampilkan 10 baris pertama dari inputnya, tidak ada jaminan bahwa itu tidak mengkonsumsi lebih banyak untuk menemukan baris ke-10 berakhir, menyisakan lebih sedikit input untuk lessditampilkan.
chepner
20
Maaf untuk mengatakan, tetapi jawabannya hanya berfungsi dalam beberapa kasus. seq 100 | (head; tail)memberi saya hanya 10 nomor pertama. Hanya pada ukuran input yang jauh lebih besar (seperti seq 2000) ekornya mendapat beberapa input.
Bagaimana jika file tersebut memiliki lebih dari 200 baris? Dan Anda tidak tahu jumlah garis ab initio?
Paul
@ Paul Saya sudah berubah sedmenjadied
kev
14
Untuk stream murni (misalnya output dari perintah), Anda dapat menggunakan 'tee' untuk memotong stream dan mengirim satu stream ke head dan satu ke tail. Ini memerlukan penggunaan fitur '> (daftar)' dari bash (+ / dev / fd / N):
( COMMAND | tee /dev/fd/3| head )3>>( tail )
atau menggunakan / dev / fd / N (atau / dev / stderr) ditambah subkulit dengan pengalihan rumit:
(( 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
(Tidak satu pun dari ini akan bekerja dalam csh atau tcsh.)
Untuk sesuatu dengan kontrol yang sedikit lebih baik, Anda dapat menggunakan perintah perl ini:
COMMAND | perl -e 'my $size = 10; my @buf = (); while (<>) { print if $. <= $size; push(@buf, $_); if ( @buf > $size ) { shift(@buf); } } print "------\n"; print @buf;'
+1 untuk dukungan streaming. Anda dapat menggunakan kembali stderr:COMMAND | { tee >(head >&2) | tail; } |& other_commands
jfs
2
btw, rusak untuk file yang lebih besar dari ukuran buffer (8K pada sistem saya). cat >/dev/nullmemperbaikinya:COMMAND | { tee >(head >&2; cat >/dev/null) | tail; } |& other_commands
jfs
Aku mencintai solusi, tapi setelah bermain untuk aa sementara saya melihat bahwa dalam beberapa kasus ekor berlari sebelum kepala ... ada ada dijamin pemesanan antara headdan tailperintah: \ ...
Jan
7
(sed -u 10q; echo ...; tail)< file.txt
Hanya variasi lain pada (head;tail)tema, tetapi menghindari masalah isi buffer awal untuk file kecil.
Bagus, saya selalu menggunakan catdan headatau taildisalurkan, senang mengetahui bahwa saya dapat menggunakannya secara individual!
Paul
Bagaimana saya bisa mem-pipe 10 + 10 ini dulu ke perintah lain?
toop
1
@ Paul - dengan 'program_Anda sebagai wc -l mengembalikan 10 bukannya 20
toop
3
atau, tanpa harus menelurkan subkulit: { head file; tail file; } | prog(spasi di dalam kurung, dan tanda titik koma diperlukan)
glenn jackman
1
Wow ... suara untuk memiliki jawaban yang sangat mirip dengan yang lain (belum dicap sebelum) setelah hampir dua tahun, dari seseorang yang memilih untuk tidak memposting mengapa mereka memilih. Bagus!
masalahnya di sini adalah bahwa program yang berorientasi pada aliran tidak tahu panjang file di muka (karena mungkin tidak ada, jika itu adalah aliran nyata).
alat-alat seperti tailbuffer n baris terakhir terlihat dan menunggu akhir aliran, lalu cetak.
jika Anda ingin melakukan ini dalam satu perintah (dan membuatnya bekerja dengan offset apa pun, dan jangan ulangi baris jika tumpang tindih) Anda harus meniru perilaku yang saya sebutkan ini.
coba awk ini:
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
Saya telah mencari solusi ini untuk sementara waktu. Mencoba sendiri dengan sed, tetapi masalah dengan tidak mengetahui panjang file / stream sebelumnya tidak dapat diatasi. Dari semua opsi yang tersedia di atas, saya suka solusi awk Camille Goudeseune. Dia memang membuat catatan bahwa solusinya meninggalkan garis kosong tambahan dalam output dengan set data yang cukup kecil. Di sini saya memberikan modifikasi dari solusinya yang menghilangkan garis ekstra.
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] }';}
Nah, Anda selalu bisa rantai mereka bersama. Seperti itu
head fiename_foo && tail filename_foo,. Jika itu tidak cukup, Anda bisa menulis sendiri fungsi bash di file .profile Anda atau file login apa pun yang Anda gunakan:
head_and_tail(){
head $1 && tail $1
}
Dan, kemudian memanggil dari shell Anda cepat: head_and_tail filename_foo.
Mengapa menggunakan cat saat Anda cukup memanggil head -10 file.txt?
jstarek
Bisakah Anda membuat jumlah baris variabel, jadi panggilannya adalah seperti: head_ tail (foo, m, n) - mengembalikan m snd terakhir terakhir n baris teks?
Ricardo
@ricardo yang akan melibatkan penulisan skrip bash yang membutuhkan 3 argumen dan meneruskannya ke taildan headatau fungsi dengan alias-ing.
Ini berfungsi untuk file dengan panjang yang diketahui, tetapi bukan file yang panjangnya tidak diketahui.
Kevin
0
Untuk menangani pipa (stream) dan juga file, tambahkan ini ke file .bashrc atau .profile Anda:
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] }';}
Maka Anda tidak bisa hanya
headtail 10< file.txt
tetapi juga
a.out | headtail 10
(Ini masih menambahkan baris kosong palsu ketika 10 melebihi panjang input, tidak seperti biasa a.out | (head; tail). Terima kasih, penjawab sebelumnya.)
Membangun apa yang dijelaskan oleh @Samus_ di sini tentang cara kerja perintah @Alexandra Zalcman, variasi ini berguna ketika Anda tidak dapat dengan cepat melihat di mana ekor dimulai tanpa menghitung garis.
Saya akan mengatakan bahwa tergantung pada ukuran file, membaca isinya secara aktif mungkin tidak diinginkan. Dalam keadaan itu, saya pikir beberapa skrip shell sederhana sudah cukup.
Inilah cara saya baru-baru ini menangani ini untuk sejumlah file CSV yang sangat besar yang saya analisis:
$ for file in*.csv;do echo "### ${file}"&& head ${file}&& echo ...&& tail ${file}&& echo;done
Ini mencetak 10 baris pertama dan 10 baris terakhir dari setiap file, sementara juga mencetak nama file dan beberapa elipsis sebelum dan sesudah.
Untuk satu file besar, Anda bisa menjalankan yang berikut untuk efek yang sama:
$ head somefile.csv && echo ...&& tail somefile.csv
Jawaban:
Anda cukup:
Dan jika Anda perlu menggunakan pipa untuk beberapa alasan maka seperti ini:
Catatan: akan mencetak baris duplikat jika jumlah baris dalam file.txt lebih kecil dari garis kepala standar + garis ekor standar.
sumber
head
mengkonsumsi 10 baris pertama file. (Bandingkan ini denganhead < file.txt; tail < file.txt
pada file dengan kurang dari 20 baris). Hanya poin yang sangat kecil untuk diingat. (Tapi tetap +1.)head
hanya menampilkan 10 baris pertama dari inputnya, tidak ada jaminan bahwa itu tidak mengkonsumsi lebih banyak untuk menemukan baris ke-10 berakhir, menyisakan lebih sedikit input untukless
ditampilkan.seq 100 | (head; tail)
memberi saya hanya 10 nomor pertama. Hanya pada ukuran input yang jauh lebih besar (sepertiseq 2000
) ekornya mendapat beberapa input.ed
adalahstandard text editor
sumber
sed
menjadied
Untuk stream murni (misalnya output dari perintah), Anda dapat menggunakan 'tee' untuk memotong stream dan mengirim satu stream ke head dan satu ke tail. Ini memerlukan penggunaan fitur '> (daftar)' dari bash (+ / dev / fd / N):
atau menggunakan / dev / fd / N (atau / dev / stderr) ditambah subkulit dengan pengalihan rumit:
(Tidak satu pun dari ini akan bekerja dalam csh atau tcsh.)
Untuk sesuatu dengan kontrol yang sedikit lebih baik, Anda dapat menggunakan perintah perl ini:
sumber
COMMAND | { tee >(head >&2) | tail; } |& other_commands
cat >/dev/null
memperbaikinya:COMMAND | { tee >(head >&2; cat >/dev/null) | tail; } |& other_commands
head
dantail
perintah: \ ...Hanya variasi lain pada
(head;tail)
tema, tetapi menghindari masalah isi buffer awal untuk file kecil.sumber
head -10 file.txt; tail -10 file.txt
Selain itu, Anda harus menulis program / skrip Anda sendiri.
sumber
cat
danhead
atautail
disalurkan, senang mengetahui bahwa saya dapat menggunakannya secara individual!{ head file; tail file; } | prog
(spasi di dalam kurung, dan tanda titik koma diperlukan)Berdasarkan komentar JF Sebastian :
Dengan cara ini Anda dapat memproses baris pertama dan lainnya secara berbeda dalam satu pipa, yang berguna untuk bekerja dengan data CSV:
sumber
masalahnya di sini adalah bahwa program yang berorientasi pada aliran tidak tahu panjang file di muka (karena mungkin tidak ada, jika itu adalah aliran nyata).
alat-alat seperti
tail
buffer n baris terakhir terlihat dan menunggu akhir aliran, lalu cetak.jika Anda ingin melakukan ini dalam satu perintah (dan membuatnya bekerja dengan offset apa pun, dan jangan ulangi baris jika tumpang tindih) Anda harus meniru perilaku yang saya sebutkan ini.
coba awk ini:
sumber
a.out | awk -v ...
Butuh banyak waktu untuk menyelesaikan dengan solusi ini yang, tampaknya menjadi satu-satunya yang mencakup semua kasus penggunaan (sejauh ini):
Daftar fitur:
sumber
Saya telah mencari solusi ini untuk sementara waktu. Mencoba sendiri dengan sed, tetapi masalah dengan tidak mengetahui panjang file / stream sebelumnya tidak dapat diatasi. Dari semua opsi yang tersedia di atas, saya suka solusi awk Camille Goudeseune. Dia memang membuat catatan bahwa solusinya meninggalkan garis kosong tambahan dalam output dengan set data yang cukup kecil. Di sini saya memberikan modifikasi dari solusinya yang menghilangkan garis ekstra.
sumber
Nah, Anda selalu bisa rantai mereka bersama. Seperti itu
head fiename_foo && tail filename_foo
,. Jika itu tidak cukup, Anda bisa menulis sendiri fungsi bash di file .profile Anda atau file login apa pun yang Anda gunakan:Dan, kemudian memanggil dari shell Anda cepat:
head_and_tail filename_foo
.sumber
10 baris file.ext pertama, lalu 10 baris terakhir:
cat file.ext | head -10 && cat file.ext | tail -10
10 baris terakhir file, lalu 10 baris pertama:
cat file.ext | tail -10 && cat file.ext | head -10
Anda kemudian dapat mengirimkan output ke tempat lain juga:
(cat file.ext | head -10 && cat file.ext | tail -10 ) | your_program
sumber
tail
danhead
atau fungsi dengan alias-ing.Saya menulis aplikasi python sederhana untuk melakukan ini: https://gist.github.com/garyvdm/9970522
Ini menangani pipa (stream) serta file.
sumber
menggambar ide di atas (bash & zsh yang diuji)
tetapi menggunakan alias 'topi' Kepala dan Ekor
sumber
Mengapa tidak digunakan
sed
untuk tugas ini?sed -n -e 1,+9p -e 190,+9p textfile.txt
sumber
Untuk menangani pipa (stream) dan juga file, tambahkan ini ke file .bashrc atau .profile Anda:
Maka Anda tidak bisa hanya
tetapi juga
(Ini masih menambahkan baris kosong palsu ketika 10 melebihi panjang input, tidak seperti biasa
a.out | (head; tail)
. Terima kasih, penjawab sebelumnya.)Catatan:,
headtail 10
tidakheadtail -10
.sumber
Membangun apa yang dijelaskan oleh @Samus_ di sini tentang cara kerja perintah @Alexandra Zalcman, variasi ini berguna ketika Anda tidak dapat dengan cepat melihat di mana ekor dimulai tanpa menghitung garis.
Atau jika Anda mulai bekerja dengan sesuatu selain 20 baris, jumlah baris bahkan mungkin membantu.
sumber
Untuk mencetak 10 baris pertama dan 10 baris terakhir dari sebuah file, Anda dapat mencoba ini:
cat <(head -n10 file.txt) <(tail -n10 file.txt) | less
sumber
CATATAN : Variabel aFile berisi path lengkap file .
sumber
Saya akan mengatakan bahwa tergantung pada ukuran file, membaca isinya secara aktif mungkin tidak diinginkan. Dalam keadaan itu, saya pikir beberapa skrip shell sederhana sudah cukup.
Inilah cara saya baru-baru ini menangani ini untuk sejumlah file CSV yang sangat besar yang saya analisis:
Ini mencetak 10 baris pertama dan 10 baris terakhir dari setiap file, sementara juga mencetak nama file dan beberapa elipsis sebelum dan sesudah.
Untuk satu file besar, Anda bisa menjalankan yang berikut untuk efek yang sama:
sumber
Mengkonsumsi stdin, tetapi sederhana dan berfungsi untuk 99% kasus penggunaan
head_and_tail
contoh
sumber