Aku ingin melakukan:
cat update_via_sed.sh | sed 's/old_name/new_name/' > new_update_via_sed.sh
dalam program saya.
Tetapi saya ingin menggunakan variabel, misalnya
old_run='old_name_952'
new_run='old_name_953'
Saya telah mencoba menggunakannya tetapi substitusi tidak terjadi (tidak ada kesalahan). Saya telah mencoba:
cat update_via_sed.sh | sed 's/old_run/new_run/'
cat update_via_sed.sh | sed 's/$old_run/$new_run/'
cat update_via_sed.sh | sed 's/${old_run}/${new_run}/'
Jawaban:
Anda bisa melakukannya:
Tapi berhati-hatilah bahwa
$old_run
akan diambil sebagai ekspresi reguler dan karakter khusus yang variabel mengandung, seperti/
atau.
harus harus melarikan diri . Demikian pula, dalam$new_run
, karakter&
dan\
perlu diperlakukan khusus dan Anda harus melarikan diri/
dan karakter baris baru di dalamnya.Jika konten
$old_run
atau$new_run
tidak di bawah kendali Anda, maka sangat penting untuk melakukan pelolosan itu, atau sebaliknya kode tersebut merupakan kerentanan injeksi kode .sumber
sed
saja tidak akan menggunakan regex tapi kansed -E
?-e
adalah untuk menentukansed
e Xpression , sehingga Anda dapat melewati lebih dari satu (seperti dalamsed -e exp1 -e exp2
) atau kombinasi dari file dan ekspresi (sed -f file -e exp
). Anda mungkin bingung dengan-E
yang mana dengan beberapa implementasi, memberitahu sed untuk menggunakan ERE bukannya BRE.-E
saya hanya menguasai regex diperpanjang bukan yang biasa. Terima kasih untuk penjelasannya.sed
implementasi untuk sintaksis ekspresi yang lebih reguler.Ini berhasil:
Karena saya ingin 'menggunakan kembali' file yang sama, saya sebenarnya menggunakan ini untuk siapa saja yang menginginkan pendekatan yang sama:
Di atas membuat file baru kemudian menghapus file saat ini daripada mengganti nama file baru menjadi file saat ini.
sumber
sed -i s/"$old"/"$new"/ update_via_sed.sh
. Namun perlu diketahui bahwa ini tidak bekerja untuk nilai lama dan baru. mis. itu tidak boleh mengandung / dll, karena $ old masih berupa pencarian dan $ new pola penggantian di mana beberapa karakter memiliki arti khusus.sed -i "s/$old/$new/"
juga ok (dengan tindakan pencegahan di atas).sed
biasanya menganggap pemisah sebagai karakter pertama setelahs
perintah - yaitu jika variabel Anda berisi garis miring/
tetapi tidak memungkinkan katakan pada (@
), Anda dapat menggunakan "s @ $ old @ $ new @".Anda bisa menggunakan variabel dalam sed selama itu dalam kuotasi ganda (bukan kuotasi tunggal):
Jika Anda memiliki garis miring (
/
) dalam variabel, maka gunakan pemisah yang berbeda seperti di bawah inisumber
|
seperti dalam kasus saya, variabel berisi path sehingga ada/
di dalamnya|
bekerja untuk saya di MacOS 10.14, tetapi pemisah lainnya suka@
atau#
tidak. Saya memiliki garis miring ke depan dalam env var saya juga.'in-place' sed (usng the -i flag) adalah jawabannya. Berkat peterph.
sumber
s@
(yang tidak khusus untuk shell dengan cara apa pun). Yang terbaik adalah memasukkan segala sesuatu di dalam tanda kutip sepertised -i "s@$old@$new@" file
. Perhatikan bahwa-i
ini bukansed
opsi standar .$
dalam perintah ini. Seperti, saya akan berubah$xxx
secara keseluruhan dengan nilai variabel$JAVA_HOME
. Saya mencobased -i "s@\$xxx@$JAVA_HOME@" file
, tetapi kesalahan mengatakanno previous regular expression
man bash
memberikan ini tentang kutipan tunggalApa pun yang Anda ketikkan pada baris perintah, bash menafsirkannya dan kemudian mengirimkan hasilnya ke program yang seharusnya dikirim. Dalam kasus ini, jika Anda menggunakan
sed 's/$old_run/$new_run/'
, bash pertama kali melihat, bashsed
mengenalinya sebagai hadiah yang dapat dieksekusi dalam$PATH
variabel . Thesed
executable membutuhkan masukan. Bash mencari input dan menemukan's/$old_run/$new_run/'
. Kutipan tunggal mengatakan bash untuk tidak menafsirkan konten di dalamnya dan meneruskannya apa adanya. Jadi, bash lalu berikan mereka sed. Sed memberikan kesalahan karena$
dapat terjadi hanya pada akhir baris.Alih-alih jika kita menggunakan tanda kutip ganda, yaitu,
"s/$old_run/$new_run/"
maka bash melihat ini dan menafsirkannya$old_run
sebagai nama variabel dan membuat substitusi (fase ini disebut ekspansi variabel). Ini memang yang kami butuhkan.Tapi, Anda harus berhati-hati menggunakan tanda kutip ganda karena, mereka ditafsirkan pertama kali oleh bash dan kemudian diberikan kepada sed. Jadi, beberapa simbol seperti `harus diloloskan sebelum menggunakannya.
sumber
Beresiko kurang ajar - sudahkah Anda pertimbangkan
perl
.Yang - antara lain - cukup bagus dalam melakukan operasi 'sed style', tetapi juga pemrograman yang lebih lengkap.
Ini terlihat seperti dalam contoh Anda, apa yang Anda benar-benar coba lakukan adalah kenaikan nomor.
Jadi bagaimana dengan:
atau sebagai one liner - sed style:
sumber
Dalam
$d1
saya menyimpan nilaiSaya tidak bisa mengganti nilai dari variabel, jadi saya mencoba perintah berikut ini berfungsi
tidak ada tanda kutip ganda
"${d1}"
, itulah kesalahannyasumber
Diasumsikan
$old_run
dan$new_run
sudah ditetapkan:Ini menunjukkan perubahan di layar. Anda dapat mengarahkan output ke file jika perlu.
sumber
Untuk menggunakan variabel dalam sed, gunakan tanda kutip ganda "", untuk menyertakan variabel, dalam pola yang Anda gunakan. Untuk misalnya: a = "Hai" Jika Anda ingin menambahkan variabel 'a' ke suatu pola, Anda dapat menggunakan yang berikut: sed -n "1, / pattern" $ {a} "pattern / p" nama file
sumber
$a
tidak dikutip di sini, yang berarti bahwa setiap spasi dalam nilainya akan meminta pemisahan kata dalam shell.Anda juga dapat menggunakan Perl:
sumber
""
) tidak akan melakukan apa pun.putus tali
bad => linux lihat string $ old_run:
good => linux lihat variabel $ old_run:
sumber
$old_run
atau$new_run
mengandung spasi?