Misalkan saya memiliki file yang berisi beberapa kemunculan StringA dan StringB. Saya ingin mengganti semua kemunculan StringA dengan StringB, dan (secara bersamaan) semua kemunculan StringB dengan StringA.
Saat ini, saya sedang melakukan sesuatu seperti
cat file.txt | sed 's/StringB/StringC/g' | sed 's/StringA/StringB/g' | sed 's/StringC/StringA/g'
Masalah dengan pendekatan ini adalah bahwa ia menganggap StringC tidak muncul dalam file. Meskipun ini bukan masalah dalam praktiknya, solusi ini masih terasa kotor — yaitu, ini terasa seperti kesempatan untuk mempelajari lebih banyak keajaiban unix.
Jawaban yang Diterima:
Jika StringB
dan StringA
tidak dapat muncul pada baris input yang sama, maka Anda dapat memberi tahu sed untuk melakukan penggantian satu cara, dan hanya mencoba cara lain jika tidak ada kemunculan string yang pertama kali dicari.
<file.txt sed -e 's/StringA/StringB/g' -e t -e 's/StringB/StringA/g'
Secara umum, saya tidak berpikir ada metode yang mudah di sed. Omong-omong, perhatikan bahwa spesifikasinya ambigu jika StringA
dan StringB
bisa tumpang tindih. Inilah solusi Perl, yang menggantikan kemunculan paling kiri dari salah satu string, dan berulang.
<file.txt perl -pe 'BEGIN {%r = ("StringA" => "StringB", "StringB" => "StringA")}
s/(StringA|StringB)/$r{$1}/ge'
Jika Anda ingin tetap menggunakan alat POSIX, awk adalah caranya. Awk tidak memiliki primitif untuk penggantian parametrized umum, jadi Anda perlu menggulung sendiri.
<file.txt awk '{
while (match($0, /StringA|StringB/)) {
printf "%s", substr($0, 1, RSTART-1);
$0 = substr($0, RSTART);
printf "%s", /^StringA/ ? "StringB" : "StringA";
$0 = substr($0, 1+RLENGTH)
}
print
}'