galat sed: "referensi tidak valid \ 1 di RHS perintah` s "


104

Saya menjalankan beberapa perintah substitusi sebagai inti dari skrip colorize untuk maven . Salah satu sedperintah menggunakan ekspresi reguler yang berfungsi menemukan di shell seperti yang dibahas di sini . Implementasi saat ini (tidak berfungsi) dapat ditemukan di sini .

Ketika saya memasukkan salah satu varian perintah ke dalam skrip, perilaku yang berbeda terjadi:

Varian 1:

$ sed -re "s/([a-zA-Z0-9./\\ :-]+)/\1/g"

Diadaptasi ke skrip:

-re "s/WARNING: ([a-zA-Z0-9./\\ :-]+)/${warn}WARNING: \1${c_end}/g" \

Kesalahan: Shell mengeluarkan informasi yang sama seperti jika saya mengetik $ sed. Aneh!?


Varian 2:

$ sed -e "s/\([a-zA-Z0-9./\\ :-]\+\)/\1/g"

Diadaptasi ke skrip:

-e "s/WARNING: \([a-zA-Z0-9./\\ :-]\+\)/${warn}WARNING: \1${c_end}/g" \

Kesalahan:

sed: -e ekspresi # 7, karakter 59: referensi tidak valid \ 1 pada RHS perintah `s '


10
Dalam kasus saya, saya telah menggabungkan -i(edit di opsi tempat) dengan -re, menghasilkan -ire(sehingga -imemakan refragmen sebagai SUFFIXargumennya dan karenanya mode regex yang diperpanjang tidak diaktifkan); mengubahnya untuk -i -rememperbaiki masalah.
Bandara Janaka

Ini juga untuk memperhatikan bahwa tanda kutip tunggal 'dan tanda kutip ganda "diperlakukan sedikit berbeda, terutama saat menafsirkan $vars. Misalnya: sudo sh -c "sed -r -i 's/(^.+_supplicant.conf)/\1${MTXT}/' /etc/network/interfaces"berfungsi, tetapi: sudo sh -c 'sed -r -i "s/(^.+_supplicant.conf)/\1${MTXT}/" /etc/network/interfaces'tidak.
not2qubit

Jawaban:


52

Apakah Anda tidak perlu benar-benar menangkapnya agar berfungsi? yaitu untuk varian 2:

-r -e "s/WARNING: (\([a-zA-Z0-9./\\ :-]\+\))/${warn}WARNING: \1${c_end}/g" \

(Catatan: belum teruji)

Tanpa -r argumen referensi-belakang (seperti \ 1) tidak akan berfungsi.


42
The -rpilihan untuk muncul sed menjadi diperlukan untuk back-referensi bekerja. Misalnya sed -e 's/([[:digit:]])/is a digit/'berfungsi tetapi sed -e 's/([[:digit:]])/\1 is a digit/menghasilkan kesalahan asli tanpa -rsed. CATATAN: pemanggilan pertama sed mencari literal (<digit>)dan bukan grup tangkap.
Andrew Falanga

Komentar di bawah jawabannya sebenarnya adalah sebuah jawaban. Mungkin Anda dapat mengedit jawaban Anda untuk mencerminkannya.
miroxlav

@AndrewFalanga Anda harus memberikan komentar Anda sebagai jawaban
sanmai

2
Tidak masalah kesalahan saya adalah menggunakan -irealih-alih menggunakan -ri. Urutan penting :-)
m3nda

54

Kesalahan ini umum terjadi pada tanda kurung yang tidak di-escape. Lari mereka dan coba lagi.


Sebagai contoh:

/^$/b
:loop
$!{
N
/\n$/!b loop
}
s/\n(.)/\1/g

Harus di-escape dengan garis miring terbalik sebelum setiap tanda kurung:

/^$/b
:loop
$!{
N
/\n$/!b loop
}
s/\n\(.\)/\1/g

6
Perhatian, jika Anda menggunakan -rAnda tidak harus keluar dari tanda kurung.
qräbnö

13

Jika opsi -r/ --regexp-extendedtidak tersedia, tanda kurung pengambilan harus di-escape.


5

Anda perlu melarikan diri /setelah.

sed -e "s/\([a-zA-Z0-9.\/\\ :-]\+\)/\1/g"

Atau jika Anda tidak ingin khawatir melarikan diri, gunakan |

sed -e "s|\([a-zA-Z0-9./\\ :-]\+\)|\1|g"

EDIT:

sed -e "s|WARNING: \([a-zA-Z0-9.-/\\ :]+\)|${warn}WARNING: \1${c_end}|g"

Kedengarannya masuk akal. Tapi itu tidak bekerja dalam konteks skrip.
JJD

Maaf. Edit menimbulkan kesalahan: sed: -e expression #7, char 58: Invalid range end. Jawaban @Denis berhasil.
JJD

2
Oke, lalu beri +1 untuk jawaban
@Denis
Dengan menggunakan situs kami, Anda mengakui telah membaca dan memahami Kebijakan Cookie dan Kebijakan Privasi kami.
Licensed under cc by-sa 3.0 with attribution required.