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 '

JJD
sumber
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.

Denis de Bernardy
sumber
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
e18r
sumber
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.

OrangeDog
sumber
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"
slackmart
sumber
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