Saya mencoba mengubah urutan garis dalam pola tertentu. Bekerja dengan file dengan banyak baris (mis. 99 baris). Untuk setiap tiga baris, saya ingin baris kedua menjadi baris ketiga, dan baris ketiga menjadi baris kedua.
CONTOH.
1- Masukan:
gi_1234
My cat is blue.
I have a cat.
gi_5678
My dog is orange.
I also have a dog.
...
2- Output:
gi_1234
I have a cat.
My cat is blue.
gi_5678
I also have a dog.
My dog is orange.
...
linux
text-processing
command-line
Annick Raymond
sumber
sumber
NR%3 == 0 { print; print delay; delay=""} END { if(length(delay) != 0 ) { print delay }
.Yaitu,
p
mematahkan garis saat ini, mendapatkan yangn
ext,h
lama itu, mendapatkan yangn
ext,G
dan garis ditahan (menambahkannya ke ruang pola) danp
melempar ruang pola 2-garis dengan baris ketiga dan kedua ditukar.sumber
Pendekatan awk lain :
Hasil:
(getline L2)>0 && (getline L3)>0
- ekstrak 2 catatan berikutnya jika adasetiap catatan ke-2 dan ke-3 ditugaskan
L2
danL3
masing-masing variabelsumber
line2
, dll.Menggunakan
perl
dan skrip pendek:Script memproses seluruh file, untuk setiap baris (disimpan dalam
$_
) itu akan mendapatkan dua baris berikutnya ($l2
dan$l3
) dan mencetaknya dalam urutan yang diminta: line1, line3, line2.sumber
Salah satu caranya bisa sebagai berikut:
Kalau tidak,
Hasil
sumber
Mengapa tidak membuat loop sementara? Dalam bentuk yang diperluas:
Dalam "format satu baris":
Output:
sumber
Perl
Idenya di sini adalah bahwa kita menggunakan operator modulo
%
dengan$.
variabel nomor baris , untuk mencari tahu mana yang pertama, mana yang setiap detik, dan mana yang setiap baris ke-3. Untuk setiap sisa baris ke-3 adalah 0, sedangkan untuk setiap baris ke-1 dan ke-2 akan memiliki angka yang sesuai.Uji:
Perbaikan kecil
Pendekatan dengan menyimpan baris kedua ke dalam variabel memiliki kelemahan. Bagaimana jika baris terakhir adalah yang "kedua", yaitu untuk nomor baris yang tersisa adalah 2? Kode asli dalam jawaban saya dan DopeGhoti tidak akan dicetak
My dog is orange
jika kami meninggalkan baris terakhir. Perbaikan untuk itu dalam kedua kasus adalah dengan menggunakanEND{}
blok kode, dengan membatalkan variabel sementara setelah pencetakan. Dengan kata lain:dan
Dengan cara ini, kode ini akan berfungsi untuk jumlah baris yang berubah-ubah dalam file, bukan hanya yang dapat dibagi 3.
Perbaikan tambahan untuk masalah yang disebutkan dalam komentar
Dalam kasus awk, jika baris terakhir dalam file menghasilkan output 1 untuk $. % 3, kode sebelumnya memiliki masalah mengeluarkan baris baru kosong karena pencetakan tanpa syarat
END{print delay}
, karenaprint
fungsi yang disebutkan dalam komentar selalu menambahkan baris baru ke variabel apa pun yang beroperasi. Dalam halperl
versi masalah ini tidak terjadi, karena dengan fungsi-ne
flagsprint
tidak menambahkan baris baru.Meskipun demikian, perbaikan dalam kasus awk adalah untuk membuat bersyarat, seperti yang disebutkan oleh Dope Ghoti dalam komentar adalah untuk memverifikasi panjang variabel sementara. Versi perl dari perbaikan yang sama adalah:
sumber
awk
)NR%3 == 0 { print; print delay; delay=""} END { if(length(delay) != 0 ) { print delay }
.-ne
bendera tidak menghasilkan baris baru. Memang mencetak, tapi itu adalah string nol, tidak ada baris baru. Nontheless, saya telah menambahkan penyebutan masalah dan perbaikan yang sama ke dalam jawaban saya. Terima kasih!Vim
Tidak cocok untuk file yang panjang, tetapi tetap berguna jika Anda hanya mengedit file dan ingin, misalnya, untuk memesan ulang beberapa bait yaml.
Rekam pertama makro:
Dan kemudian ulangi beberapa kali yang diinginkan:
Atau misalnya saja
Penjelasan:
sumber
@q @q @q
, mungkin dilakukan dengan cara ini3@q
- ulangi tiga kali.100@q
- ulangi makro 100 kali.Pemakaian:
./shuffle_lines.awk input.txt
Periksa shebang
#!/usr/bin/awk -f
, karenaawk
lokasi mungkin berbeda pada sistem Anda.sumber