Argumen negatif untuk kepala / ekor

14

Varian dari pertanyaan ini tentu telah ditanyakan beberapa kali di tempat yang berbeda, tetapi saya mencoba untuk menghapus Mbaris terakhir dari file tanpa keberuntungan.

Jawaban terbanyak kedua dalam pertanyaan ini merekomendasikan melakukan yang berikut untuk menyingkirkan baris terakhir dalam file:

head -n -1 foo.txt > temp.txt

Namun, ketika saya mencobanya di OSX & Zsh, saya mendapatkan:

head: illegal line count -- -1

Mengapa demikian? Bagaimana saya bisa menghapus M terakhir garis dan yang pertama N baris dari file yang diberikan?

Amelio Vazquez-Reina
sumber
1
Apa output dari head --version? Sistem apa yang Anda gunakan?
jofel
@ jofel head --versionsebenarnya mengembalikan kesalahan.
Amelio Vazquez-Reina

Jawaban:

20

Anda dapat menghapus 12 baris pertama dengan:

tail -n +13

(Itu berarti mencetak dari garis ke-13.)

Beberapa implementasi dukungan headseperti GNU head:

head -n -12

tapi itu bukan standar.

tail -r file | tail -n +12 | tail -r

akan bekerja pada sistem yang memiliki tail -r(lihat juga GNU tac) tetapi kurang optimal.

Dimana n1:

sed '$d' file

Anda juga dapat melakukan:

sed '$d' file | sed '$d'

untuk menghapus 2 baris, tetapi itu tidak optimal.

Anda dapat melakukan:

sed -ne :1  -e 'N;1,12b1' -e 'P;D'

Tetapi waspadalah yang tidak akan bekerja dengan nilai n yang besar dengan beberapa sedimplementasi.

Dengan awk:

awk -v n=12 'NR>n{print line[NR%n]};{line[NR%n]=$0}'

Untuk menghapus mgaris dari awal dan ndari akhir:

awk -v m=6 -v n=12 'NR<=m{next};NR>n+m{print line[NR%n]};{line[NR%n]=$0}'
Stéphane Chazelas
sumber
sed 'x;1d;$d'mungkin digunakan untuk mendapatkan dua baris terakhir juga. Dan beberapa Nsetelah 1dmungkin dapat digunakan untuk mendapatkan sedikit lebih dari itu, meskipun pada saat itu ia tidak menawarkan keuntungan atas N;P;Dloop yang sudah Anda rekomendasikan.
mikeserv
Terima kasih - Perintah terakhir sangat membantu. Peringatan kecil musim panas: tidak berfungsi kapan matau nsedang 0. Kalau tidak, itu akan sempurna.
Amelio Vazquez-Reina
2

Anda dapat menggunakan cara berikut untuk menghapus garis N pertama dan garis M terakhir.

Dengan N=5, M=7dan ajukan test.txt:

sed -n -e "6,$(($(wc -l < test.txt) - 7))p" test.txt

Perintah ini mencetak semua baris dari N +1 ke LastLine-M.

Pilihan lain adalah menggunakan python:

python -c 'import sys;print "".join(sys.stdin.readlines()[5:-7]),' < test.txt
Jofel
sumber
1

Anda dapat menghapus baris terakhir M(di sini M = 100) dari file dengan:

head -$(($(wc -l < foo.txt) - 100)) foo.txt > temp.txt
membuat
sumber