Saya sering menemukan ini dalam skrip (dan, saya harus akui, tulis sendiri):
a=$(echo "$x" | sed "s/foo/bar/")
atau
if echo "$x" | grep -q foo
then
...
fi
Pertimbangkan "foo" untuk memasukkan beberapa hal regex.
Saya merasa bahwa harus ada - dan kemungkinan besar adalah - cara yang lebih baik untuk frase ini, yang tidak melibatkan dua perintah dan pipa tetapi membungkusnya menjadi beberapa ekspresi yang lebih kompak.
Saya tidak bisa menemukannya. Siapa saja?
$()
daripada backticks.a="$(echo "$x" | sed "s/foo/bar/")"
danif echo "$x" | grep foo; …
.Jawaban:
Kecuali Anda mengasumsikan shell tertentu, tidak ada cara yang lebih baik untuk melakukan ini selain "pipe echo to tool" (atau hanya "tool" itu sendiri seperti expr ); hanya itu yang bisa Anda andalkan dengan cangkang Bourne tradisional dan / atau cangkang POSIX . Jika Anda mempertimbangkan cangkang lain, maka ada beberapa kemungkinan bawaan lainnya.
ksh punya
?(pattern-list)
,*(pattern-list)
,{n}(pattern-list)
,{n,m}(pattern-list)
,@(pattern-list)
,!(pattern-list)
;%P
printf specifier untuk mengkonversi ekspresi reguler diperpanjang ke dalam pola (dan%R
untuk ekspresi reguler diperpanjang pola);expr == pattern
kondisi di[[ expr ]]
tes;${param/pattern/replacement}
ekspansi parameter.bash punya
extglob
pilihan untuk mengaktifkan sebagian besar pola tambahan ksh (tidak ada{n}
dan{n,m}
);expr == pattern
kondisi (di[[ expr ]]
tes);${param/pattern/replacement}
ekspansi parameter;expr =~ extregexp
kondisi (dalam[[ expr ]]
pengujian) yang dapat cocok dengan ekspresi reguler yang diperluasBASH_REMATCH
parameter, penggantian gaya sed dapat dilakukan.zsh memiliki
EXTENDED_GLOB
opsi;KSH_GLOB
opsi;expr == pattern
kondisi (di[[ expr ]]
tes);${pattern/pattern/replacement}
ekspansi parameter;expr =~ extregexp
kondisi (di[[ expr ]]
tes) yang bisa cocok melawan ekspresi reguler diperpanjang,MATCH
parameter, danmatch
parameter (atauBASH_REMATCH
denganBASH_REMATCH
set opsi), penggantian gaya sed dapat dilakukan;zsh/pcre
modul yang menawarkanpcre_compile
,pcre_study
danpcre_match
perintah dan-pcre-match
tes kondisi (di[[ expr ]]
tes);zsh/regex
modul yang menawarkan-regex-match
tes kondisi (di[[ expr ]]
tes).sumber
Untuk mengganti garis sed, lakukan sesuatu seperti
${a/foo/bar}
atau${a//foo/bar}
Dalam bentuk pertama, hanya instance pertama yang diganti. Bentuk kedua adalah pencarian global & ganti.
Dalam kasus Anda, itu akan menjadi
Dari pada:
Pertimbangkan menggunakan:
Di mana
foo
ekspresi reguler.sumber
if [ $x =~ foo ]
memberikan pesan kesalahan di sini.if [[ $x =~ foo ]]
Namun, bekerja dengan baik. Terima kasih!=~
membutuhkan bash> = 3 iirc.${a##foo}
dan${a%%bar}
.=~
memang menggunakan ekspresi reguler. Ini benar, misalnya:[[ "abcdddde" =~ ^a.*d+.g* ]]
( misalnya nol atau lebih g daripada wildcard, misalnya).Cara yang kompatibel dengan posix yang baik untuk menguji apakah suatu variabel berisi pola adalah:
Sintaks dari perluasan parameter adalah:
di mana
pattern
adalah pola shell .sumber