Masalah ini mungkin sebenarnya paling mudah dilakukan ed, karena itu pada dasarnya adalah editor teks yang dapat skrip, daripada prosesor aliran. Menggunakan ed, Anda tidak harus menyimpan semua baris file ke dalam array, misalnya, karena sudah melakukan itu untuk Anda.
# Create test file
~> printf "%s\n" aaaaaa bbbbbb cccccc dddddd eeeeee >test.txt
~> cat test.txt
aaaaaa
bbbbbb
cccccc
dddddd
eeeeee
# Use ed to open the file, move the last line after the first, save, and quit
~> printf "%s\n" '$m1' wq | ed test.txt
35
35
~> cat test.txt
aaaaaa
eeeeee
bbbbbb
cccccc
dddddd
sed '$x;1!H;1p;$!d;x;s/\n//
' <<\IN
aaaaaa
bbbbbb
cccccc
dddddd
eeeeee
IN
... yang akan Hmenua setiap baris yang !bukan yang pertama, dan yang pertama pruntuh. Pada $baris terakhir, ia xmengubah ruang pegang dan pola sebelum melakukan yang Hlama - yang membuat baris yang disimpan ditambahkan ke baris terakhir - lalu dmenghapus dari output semua baris yang !bukan yang $terakhir.
Pada $baris terakhir, ia xmengubah spasi lagi, s///mengganti \nkarakter ewline pertama - yang mengatur tambahan yang ditambahkan pada baris 2 - lalu mencetak ulang otomatis lot.
KELUARAN:
aaaaaa
eeeeee
bbbbbb
cccccc
dddddd
tanpa menggunakan buffer Tahan:
cat <<\IN >infile
aaaaaa
bbbbbb
cccccc
dddddd
eeeeee
IN
... hanya untuk menyimpan contoh Anda ke file yang sebenarnya ...
sed '1p;$!d;r infile' <infile | sed '3d;$d'
Bahwa pengalihan <infiledengan yang pertama sed's stdin, yang hanya prints baris pertama sebelum deleting dari output semua baris yang !tidak $terakhir. Baris terakhir adalah autoprinted, tetapi juga satu-satunya jalur yang perintah akhir dijalankan - yang adalah untuk rEAD keluar seluruh yang infilelagi ke stdout. Semua itu akan dilewati |pipa ke yang kedua sedyang kemudian hanya harus dmenghapus dari outputnya jalur input ketiga dan terakhir untuk menyelesaikan mengatur ulang.
Anda menyimpan setiap baris dalam aarray, lalu mencetak array dalam urutan yang Anda inginkan (baris 1, baris terakhir ( NR) dan dari 2 hingga kedua dari belakang.
Menggunakan kombinasi kepala / ekor dan sed:
~$ head -1 f;tail -1 f;sed '1d;$d' f
aaaaaa
eeeeee
bbbbbb
cccccc
dddddd
Cetak baris pertama, terakhir, dan dengan sed hapus 1 dan terakhir.
Dengan sed saja, saya hanya dapat menemukan perintah ini. Saya yakin ada cara yang lebih baik:
~$ sed '${p;x;s/^\n//;p};2,${H;d}' f
aaaaaa
eeeeee
bbbbbb
cccccc
dddddd
Jika ini adalah baris pertama, cetaklah (default).
Dari baris kedua, letakkan di buffer terus ( H), dan hapus dari ruang pola ( d). Dan jika itu adalah baris terakhir, cetaklah ( p), lalu dapatkan buffer penahan ( x), hapus baris kosong ( s/^\n//) dan cetaklah ( p).
awk
solusi, apakah Andased
penggemar berat atau mungkin Anda menulissed
? ;-)awk
- saya belum pernah mencoba. mungkin suatu hari nanti ...Pendekatan naif menggunakan awk:
Anda menyimpan setiap baris dalam
a
array, lalu mencetak array dalam urutan yang Anda inginkan (baris 1, baris terakhir (NR
) dan dari 2 hingga kedua dari belakang.Menggunakan kombinasi kepala / ekor dan sed:
Cetak baris pertama, terakhir, dan dengan sed hapus 1 dan terakhir.
Dengan sed saja, saya hanya dapat menemukan perintah ini. Saya yakin ada cara yang lebih baik:
Jika ini adalah baris pertama, cetaklah (default).
Dari baris kedua, letakkan di buffer terus (
H
), dan hapus dari ruang pola (d
). Dan jika itu adalah baris terakhir, cetaklah (p
), lalu dapatkan buffer penahan (x
), hapus baris kosong (s/^\n//
) dan cetaklah (p
).sumber
sed
bagian itu akan menjadi sesuatu sepertihead -n -1 f | tail -n +2
.-1
sintaks untukhead
tidak portabel.Dengan perl:
Dengan awk:
KELUARAN
sumber