Jika baris komentar yang ada membentuk satu blok bersebelahan, maka Anda bisa mencocokkan dari baris komentar pertama , mengomentari hanya garis-garis tersebut hingga dan termasuk pola akhir Anda yang belum dikomentari
sed '/^#/,/dotan/ s/^[^#]/#&/' file
Jika komentar yang ada tidak berdekatan, maka karena sifat serakah dari pertandingan sed range saya pikir Anda perlu melakukan sesuatu seperti
tac file | sed '/dotan/,/^#/ s/^[^#]/#&/' | tac
yaitu mencocokkan ke atas dari pola akhir ke komentar 'pertama' - jelas itu tidak begitu nyaman jika Anda menginginkan solusi di tempat.
Anda dapat menangani kedua kasus (baris komentar dalam satu blok yang berdekatan atau diselingi di antara baris yang tidak dikomandoi) dengan satu sedpermintaan:
sed '1,/PATTERN/{/^#/{x;1d;b};//!{H;/PATTERN/!{1h;d};//{x;s/\n/&#/g}}}' infile
Ini hanya memproses garis dalam 1,/PATTERN/rentang. Itu xperubahan terus ruang w. ruang pola setiap kali sebuah baris dikomentari (jadi tidak pernah ada lebih dari satu baris yang dikomentari dalam ruang tunggu) dan menambahkan setiap baris yang tidak dikomentari ke Hruang lama (ketika pada baris pertama, 1ddan masing 1h- masing juga diperlukan untuk menghapus inisial baris kosong di buffer penahan).
Ketika mencapai POLA pencocokan garis, itu juga menambahkannya ke Hbuffer lama, e xmengubah buffer dan kemudian mengganti setiap \nkarakter ewline dalam ruang pola dengan \newline dan #(yaitu, semua garis dalam ruang pola sekarang akan dimulai dengan #, termasuk baris pertama sebagai baris pertama di ruang tunggu selalu merupakan baris yang dikomentari).
Dengan sampel infile:
alice
#bob
bill
#charlie
ding
dong
dotan
jimmy
#garry
berlari:
sed '1,/dotan/{ # if line is in this range -start c1
/^#/{ # if line is commented -start c2
x # exchage hold space w. pattern space
1d # if 1st line, delete pattern space
b # branch to end of script
} # -end c2
//!{ # if line is not commented -start c3
H # append to hold space
/dotan/!{ # if line doesn't match dotan -start c4
1h # if 1st line, overwrite hold space
d # delete pattern space
} # -end c4
//{ # if line matches dotan -start c5
x # exchage hold space w. pattern space
s/\n/&#/g # add # after each newline character
} # -end c5
} # -end c3
}' infile # -end c1
output:
alice
#bob
bill
#charlie
#ding
#dong
#dotan
jimmy
#garry
jadi itu hanya mengomentari baris dari (dan tidak termasuk) #charliehingga (dan termasuk) dotandan membiarkan baris lain tidak tersentuh.
Tentu, ini mengasumsikan selalu ada setidaknya satu baris komentar sebelum pencocokan baris PATTERN. Jika bukan itu masalahnya, Anda dapat menambahkan cek tambahan sebelum penggantian:/^#/{s/\n/&#/g}
Itu sesuai dengan yang Anda minta. Ini hanya bekerja pada tumpukan - membangunnya bila perlu dan selama diperlukan antara kemunculan baris yang dikomentari, dan membuang buffer lama demi baris komentar baru lebih lanjut di input ketika menemukan satu. Gambar...
Maaf, saya tidak tahu mengapa saya melakukan itu. Tapi itu terlintas dalam pikiran.
Bagaimanapun, sedsebarkan buffernya di antara setiap baris komentar terakhir dalam seri apa pun, jangan pernah menyimpan satu pun buffer lebih dari yang diperlukan untuk secara akurat melacak kejadian yang terakhir dikomentari, dan jika sewaktu-waktu ia menemukan baris terakhir saat melakukan itu akan mencoba gpernyataan eksekusi lobal terakhir dan cabang tseluruh buffer keluar untuk dicetak, kalau tidak itu akan Pmembatalkan semua baris yang dilepaskan dari buffer segera setelah itu.
Saya kira inilah yang membawa akordeon ke pikiran ...
printf %s\\n \#alice \#bob charlie dotan eric \
\#alice \#bob charlie dotan eric \
\#alice \#bob charlie dotan eric |
sed -e:n -e'l;/\n#.*\ndotan/!{$!{N;/^#/bn' \
-eb -e\} -e'/^#/s/\(\n\)\(dotan.*\)*/\1#\2/g' \
-et -e\} -eP\;D
#alice
#alice\n#bob$
#alice\n#bob\ncharlie$
#alice\n#bob\ncharlie\ndotan$
#alice
#bob\ncharlie\ndotan$
#bob\ncharlie\ndotan\neric$
#bob\ncharlie\ndotan\neric\n#alice$
#bob\ncharlie\ndotan\neric\n#alice\n#bob$
#bob\ncharlie\ndotan\neric\n#alice\n#bob\ncharlie$
#bob\ncharlie\ndotan\neric\n#alice\n#bob\ncharlie\ndotan$
#bob
charlie\ndotan\neric\n#alice\n#bob\ncharlie\ndotan$
charlie
dotan\neric\n#alice\n#bob\ncharlie\ndotan$
dotan
eric\n#alice\n#bob\ncharlie\ndotan$
eric
#alice\n#bob\ncharlie\ndotan$
#alice
#bob\ncharlie\ndotan$
#bob\ncharlie\ndotan\neric$
#bob\ncharlie\ndotan\neric\n#alice$
#bob\ncharlie\ndotan\neric\n#alice\n#bob$
#bob\ncharlie\ndotan\neric\n#alice\n#bob\ncharlie$
#bob\ncharlie\ndotan\neric\n#alice\n#bob\ncharlie\ndotan$
#bob
charlie\ndotan\neric\n#alice\n#bob\ncharlie\ndotan$
charlie
dotan\neric\n#alice\n#bob\ncharlie\ndotan$
dotan
eric\n#alice\n#bob\ncharlie\ndotan$
eric
#alice\n#bob\ncharlie\ndotan$
#alice
#bob\ncharlie\ndotan$
#bob\ncharlie\ndotan\neric$
#bob
#charlie
#dotan
eric
Hanya ada satu perbedaan antara perintah ini dan yang di atas dan itu adalah lperintah ook di atas. Ketika kita lmelihat sedruang pola saat berfungsi, kita bisa mendapatkan ide yang lebih baik tentang apa yang terjadi di balik layar dan pemahaman yang lebih baik tentang bagaimana mengarahkan usahanya.
Dalam hal ini kita dapat menonton sedinput tumpukan hingga menemukan kemunculan \n#.*\ndotaninput kedua, dan ketika itu mulai mencetak baris sebelumnya pada satu waktu. Agak keren. Saya belajar banyak tentang ini.
Sangat baik terima kasih! Paragraf terakhir dengan penjelasannya luar biasa, saya akan meluangkan cukup banyak waktu untuk belajar dari pos ini juga. Tumpukan bagus!
dotancohen
1
@dotancohen - ini pertanyaan yang sangat bagus. Lihatlah hasil edit untuk melihat tumpukan .
mikeserv
2
Saya perhatikan dalam riwayat edit entri Handle many dotans. Saya yakin ini adalah mimpi terburuk istri saya.
dotancohen
1
@dotancohen - ya, ini yang sulit. Hal-hal seperti #\ndotan\ndotansulit untuk hal-hal ini. Maksud saya ketika saya mengatakan ini pertanyaan yang bagus. Saya pikir saya mendapatkannya dengan sempurna, tetapi satu masalah yang bisa Anda temui adalah jika blok komentar Anda dipisahkan oleh 1000 baris - yang akan memperlambatnya. Anda mungkin menempel sesuatu seperti s/\n/&/150;tsebelum /\n#hal pertama untuk keluar buffer jika itu mencakup 150 baris, misalnya. Dan lagi pula, mungkin itu hanya apa yang dia telah menunggu sepanjang !
Ini yang lain
sed
:Itu sesuai dengan yang Anda minta. Ini hanya bekerja pada tumpukan - membangunnya bila perlu dan selama diperlukan antara kemunculan baris yang dikomentari, dan membuang buffer lama demi baris komentar baru lebih lanjut di input ketika menemukan satu. Gambar...
Maaf, saya tidak tahu mengapa saya melakukan itu. Tapi itu terlintas dalam pikiran.
Bagaimanapun,
sed
sebarkan buffernya di antara setiap baris komentar terakhir dalam seri apa pun, jangan pernah menyimpan satu pun buffer lebih dari yang diperlukan untuk secara akurat melacak kejadian yang terakhir dikomentari, dan jika sewaktu-waktu ia menemukan baris terakhir saat melakukan itu akan mencobag
pernyataan eksekusi lobal terakhir dan cabangt
seluruh buffer keluar untuk dicetak, kalau tidak itu akanP
membatalkan semua baris yang dilepaskan dari buffer segera setelah itu.Saya kira inilah yang membawa akordeon ke pikiran ...
Hanya ada satu perbedaan antara perintah ini dan yang di atas dan itu adalah
l
perintah ook di atas. Ketika kital
melihatsed
ruang pola saat berfungsi, kita bisa mendapatkan ide yang lebih baik tentang apa yang terjadi di balik layar dan pemahaman yang lebih baik tentang bagaimana mengarahkan usahanya.Dalam hal ini kita dapat menonton
sed
input tumpukan hingga menemukan kemunculan\n#.*\ndotan
input kedua, dan ketika itu mulai mencetak baris sebelumnya pada satu waktu. Agak keren. Saya belajar banyak tentang ini.sumber
Handle many dotans
. Saya yakin ini adalah mimpi terburuk istri saya.#\ndotan\ndotan
sulit untuk hal-hal ini. Maksud saya ketika saya mengatakan ini pertanyaan yang bagus. Saya pikir saya mendapatkannya dengan sempurna, tetapi satu masalah yang bisa Anda temui adalah jika blok komentar Anda dipisahkan oleh 1000 baris - yang akan memperlambatnya. Anda mungkin menempel sesuatu sepertis/\n/&/150;t
sebelum/\n#
hal pertama untuk keluar buffer jika itu mencakup 150 baris, misalnya. Dan lagi pula, mungkin itu hanya apa yang dia telah menunggu sepanjang !