Apa kebalikan dari kepala? Saya ingin semua kecuali N baris pertama file


142

Diberi file teks yang panjangnya tidak diketahui, bagaimana saya bisa membaca, misalnya semua kecuali 2 baris pertama file? Saya tahu tailakan memberi saya N baris terakhir, tapi saya tidak tahu apa N sebelumnya.

Jadi untuk sebuah file

AAAA
BBBB
CCCC
DDDD
EEEE

saya ingin

CCCC
DDDD
EEEE

Dan untuk sebuah file

AAAA
BBBB
CCCC

Saya akan mendapatkan saja

CCCC

Jawaban:


211

tail --help memberikan yang berikut:

  -n, --lines=K            output the last K lines, instead of the last 10;
                           or use -n +K to output lines starting with the Kth

Jadi untuk memfilter 2baris pertama , -n +3harus memberi Anda output yang Anda cari (mulai dari 3).


2
Anehnya, halaman manual saya tidak mencantumkan opsi, tetapi berfungsi dengan baik - terima kasih!
Nicholas MT Elliott

@ Nicholas: Aneh, saya pikir itu akan menjadi dokumentasi standar terlepas dari OS. Saya menariknya dari Cygwin di dalam Windows, jadi saya tidak tahu seperti apa di berbagai distro Linux. Senang itu berhasil.
Joe Enos

@NicholasMTElliott man7 mencantumkannya seperti halaman manual Joe Enos, jadi sepertinya ini adalah versi masalah halaman manual
Uli Köhler

@SteveJorgensen: Saya tidak mengerti apa yang dimaksud dengan komentar Anda; tidak ada yang menyarankan untuk menggunakan headini?
ruakh

22

Dengan asumsi versi ekor Anda mendukungnya, Anda dapat menentukan mulai ekor setelah garis X. Dalam kasus Anda, Anda akan melakukan 2 +1.

tail -n +3

[mdemaria@oblivion ~]$ tail -n +3 stack_overflow.txt
CCCC
DDDD
EEEE

12

Solusi sederhana menggunakan awk:

awk 'NR > 2 { print }' file.name

Salah satu dari kita bingung. Pertanyaan mengatakan: "semua kecuali 2 baris pertama file". Bagaimana perintah itu tidak memenuhi persyaratan?
Janm

6
{ print }adalah tindakan default, dan dapat dihilangkan.
tripleee

8

Coba sed 1,2d. Ganti 2 sesuai kebutuhan.


bekerja seperti yang diharapkan .. karena jumlah baris setelah 2 baris pertama tidak diketahui.
kumarprd

6

tail -n +linecount filenameakan mulai produksi pada baris linecountdari filename, sehingga tail -n +3 filename harus melakukan apa yang Anda inginkan.


Ini tidak akan bekerja di shell saya tetapi tail -n +17 filenameakan. Saya menggunakan bash / ubuntu LTS
isomorphismes

2
@ iso: Terima kasih atas head-up - versi yang lebih lama tailmenerima sintaks yang saya gunakan dalam jawaban asli saya, tetapi sekarang orang perlu menggunakan -nopsi eksplisit . Saya telah memperbarui jawaban saya sesuai dengan itu.
Jim Lewis

0

Gunakan ini, seandainya sampel pertama disebut sample1.dat maka tail --lines=3 sample1.datyang akan mencetak semua baris dari baris ke-3 ke baris terakhir.

Untuk sampel kedua, sekali lagi anggaplah itu disebut sample2.dat tail --lines=-1 sample2.datyang akan mencetak baris terakhir ...


@ Jim: apa bedanya dengan Anda dan milik saya? .... hal yang sama ....: o Saya merujuk pada dua sampel input file data sesuai pertanyaannya dan menunjukkan bagaimana mencapai apa yang ia cari ... .
t0mm13b

Ok ... lalu mengapa dia meminta sampel kedua dan menunjukkan hasil yang dia inginkan yang saya gunakan 'tail --lines = -1' ...... tentu saja Anda dapat menghilangkan nama file sepenuhnya dan masih dapat bertindak sebagai pipa ... hmm
t0mm13b

@ommie: Ups, lupakan apa yang saya katakan tentang pipa ... Saya pasti telah memikirkan beberapa utilitas lain. Tetapi poin saya adalah bahwa satu perintah,, tail +3 anyfilememberikan hasil yang diinginkan untuk kasus umum, sementara tail --lines=Nmembutuhkan pengetahuan N terlebih dahulu untuk memberikan hasil yang diinginkan.
Jim Lewis

@ommie: Tapi ini tail... bukankah itu seharusnya menjadi "pantat"? (Ba-dum TISH! Terima kasih, saya akan berada di sini sepanjang minggu ...)
Jim Lewis

0

Saya benar-benar tidak tahu bagaimana melakukannya hanya dari ekor atau kepala tetapi dengan bantuan wc -l(jumlah baris) dan ekspresi bash, Anda dapat mencapainya.

tail -$(( $( wc -l $FILE | grep -Eo '[0-9]+' ) - 2 )) $FILE

Semoga ini membantu.


1
Ini membutuhkan lulus penuh file sebelum menjalankan ekor. Jika file lebih besar dari ukuran memori, ini akan sangat tidak efisien. Itu tidak menangani file kurang dari dua baris. Itu tidak menangani perubahan ukuran file antara wc dan ekor.
Januari

2
@janm: Anda baik-baik saja. Jawaban lain lebih baik. Saya merasa malu. :-p
NawaMan

-1

menggunakan awk untuk mendapatkan semua kecuali 2 baris terakhir

awk 'FNR==NR{n=FNR}FNR<=n-3{print}' file file

awk untuk mendapatkan semua kecuali 2 baris pertama

awk 'NR>2' file

ATAU Anda dapat menggunakan lebih banyak

more +2 file

atau hanya bash

#!/bin/bash

i=0
while read -r line
do
  [[ $i > 1 ]] && echo "$line"
  ((i++))
done <"file"

Sekarang ini tidak memenuhi persyaratan. Pertanyaannya mengatakan "semua kecuali 2 baris pertama dari file" dan memberikan dua contoh, masing-masing dengan satu file, di mana dua baris pertama dilewati dan sisanya dari file dikirim ke stdout. Bukan itu yang dilakukan perintah ini.
Januari

ya saya salah membaca pertanyaan. pikir dia meminta semua kecuali 2 baris terakhir.
ghostdog74
Dengan menggunakan situs kami, Anda mengakui telah membaca dan memahami Kebijakan Cookie dan Kebijakan Privasi kami.
Licensed under cc by-sa 3.0 with attribution required.