Tại sao sed lại cho tôi một lỗi về một 's' bị hủy diệt?


9

Tôi có một tập hợp thay thế sed trong tập lệnh bash và đang gặp lỗi về lệnh `s 'bị hủy. Đây là dòng sed trông như thế nào:

sed -n -e "s/TMPFOO1/$FOO1/" -e "s/TMPFOO2/$FOO2/" -e "s/TMPFOO3/$FOO3/" -e "s/TMPFOO4/$FOO4/" -e "s/TMPFOO5/$FOO5/" /home/foo/template > /home/foo/template/finishedresult

Vì một số lý do, bash không thích điều này và tôi gặp lỗi về

sed: -e expression #4, char 69: unterminated `s' command

Tôi đang thiếu gì ở đây? Làm thế nào tôi có thể có SED đầu vào biến? Có vẻ như tất cả họ đều chấm dứt.


2
$ FOO4 chứa một cái gì đó kỳ lạ (ví dụ: "\" hoặc "\\"?) Khiến lệnh sed s không bị chấm dứt. (Đó là lý do tại sao tôi nghĩ rằng đó là một dấu "\", làm tiếp theo "/" được coi là một phần tính cách của chuỗi thay thế, thay vì là nhân vật chấm dứt cho s lệnh)
Olivier Dulac

Câu trả lời:


7

Bạn không thể nội suy một cách an toàn một biến trong lệnh sed, bởi vì sự thay thế được thực hiện bởi shell chứ không phải bởi sed. Giá trị của biến trở thành cú pháp sed. Ví dụ: trong "s/TMPFOO1/$FOO1/", nếu $FOO1chứa một dòng mới, điều này sẽ gây ra lỗi cú pháp giống như lỗi bạn quan sát. Nếu $FOO1chứa a /, điều này chấm dứt slệnh và có thể gây ra lỗi hoặc có thể khiến các lệnh khác được thực thi (nếu sau đó /xảy ra là cú pháp sed hợp lệ).

Mặc dù bạn có thể thực hiện lần đầu tiên thay thế FOO1để trích dẫn các ký tự đặc biệt của nó để đưa vào lệnh sed đó, việc sử dụng awk đơn giản hơn nhiều. Awk có một khái niệm về biến và cú pháp dòng lệnh để đặt giá trị ban đầu của một biến.

awk -v FOO1="$FOO1" -v FOO2="$FOO2" -v FOO3="$FOO3" -v FOO4="$FOO4" -v FOO5="$FOO5" '{
    sub(/TMPFOO1/, FOO1);
    sub(/TMPFOO2/, FOO2);
    sub(/TMPFOO3/, FOO3);
    sub(/TMPFOO4/, FOO4);
    sub(/TMPFOO5/, FOO5);
    print;
}' /home/foo/template > /home/foo/template/finishedresult

Lưu ý tầm thường: - một -vnhu cầu đi trước mỗi khai báo biến.
Mike B

@MikeB Cảm ơn báo cáo lỗi. Nói chung, vui lòng chỉnh sửa bài đăng trực tiếp khi bạn tìm thấy lỗi chính tả như thế này.
Gilles 'SO- ngừng trở nên xấu xa'

@Gilles Chỉnh sửa từ những người không phải là tác giả phải có ít nhất sáu ký tự.
NobleUplift

6

Nhiều khả năng một trong các $FOObiến của bạn chứa các ký tự đặc biệt được diễn giải bởi sed.

Tôi có một phiên bản sedkhác tạo ra các thông báo lỗi khác nhưng đây là một ví dụ về một vấn đề tương tự:

$ VAR=a
$ echo i | sed -e "s/i/"$VAR"/"
a
$ tmp> VAR=/
$ echo i | sed -e "s/i/"$VAR"/"
sed: 1: "s/i///
": bad flag in substitute command: '/'

Trong trường hợp $VARnày có chứa một ký tự được hiểu sedlà dấu gạch chéo.


2

Như những người khác đã đề cập ở đây, nó phụ thuộc vào nội dung của các biến FOO * của bạn. Trong trường hợp của bạn, sử dụng sedlà lựa chọn sai bởi vì nó có thể chứa một số ký tự đặc biệt.

Hãy xem liên kết này và xem chức nănggsub_literal

gsub_literalđọc từ stdin và ghi vào thiết bị xuất chuẩn, nên cách sử dụng sẽ là:

gsub_literal "$search" "$replace" < /home/foo/template > /home/foo/template/finishedresult

Đầu ra mẫu:

rany$ cat > foo.txt
a'
a'

rany$ gsub_literal a\' b < foo.txt 
b
b

1

Vấn đề đã được giải quyết cho tôi bằng cách thử thêm dấu gạch chéo ngược trong sed 's/.../.../g'lệnh. Lệnh này

sed 's/\"a/ä/g' input_file

đưa cho tôi thông báo lỗi này

sed: -e biểu thức # 1, char 9: lệnh `s 'bị hủy

khi nó được thực thi như một phần của tập lệnh c-shell và nó chỉ làm như vậy với phiên bản gần đây sedchứ không phải với phiên bản cũ hơn. (Thật kỳ lạ, cùng một lệnh hoạt động tốt khi nó được đưa ra trên dòng lệnh (trong một tc-shell)).

Sự cố với tập lệnh c-shell đã được khắc phục bằng cách đặt trước äký tự bằng dấu gạch chéo ngược:

sed 's/\"a/\ä/g' input_file
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.