Sử dụng tài liệu ở đây cho `sed` và một tệp


10

Tôi muốn sử dụng tài liệu tại đây cho các lệnh sed và cung cấp tệp cần đọc và tệp đầu ra.

Tôi đã xem Tài liệuđây từ Hướng dẫn về Bash Bash nâng cao nhưng nó không đề cập bất cứ điều gì về các đối số thông thường khi sử dụng tài liệu ở đây. Nó thậm chí có thể?

Tôi muốn đạt được một cái gì đó như sau:

#!/bin/bash
OUT=/tmp/outfile.txt
IN=/my_in_file.txt

sed $IN << SED_SCRIPT
    s/a/1/g
    s/test/full/g

SED_SCRIPT 
> $OUT;

Bất kỳ trợ giúp được thực sự đánh giá cao.

Câu trả lời:


14

Bạn có thể yêu cầu GNU sed đọc tập lệnh từ đầu vào tiêu chuẩn -f -, -fnghĩa là đọc tập lệnh từ một tập tin và -có nghĩa là đầu vào tiêu chuẩn là phổ biến với rất nhiều lệnh.

sed -f - "$IN" > "$OUT" << SED_SCRIPT
    s/a/1/g
    s/test/full/g
SED_SCRIPT

POSIX sed cũng hỗ trợ -f, nhưng việc sử dụng -cho đầu vào tiêu chuẩn không được ghi lại. Trong trường hợp này, bạn có thể sử dụng /dev/stdintrên các hệ thống Linux (và tôi dường như nhớ lại Solaris cũng có điều này, nhưng tôi không thể xác nhận điều đó ngay bây giờ)

Sử dụng <<-SED_SCRIPT(với tiền tố '-') sẽ cho phép SED_SCRIPTthẻ đóng được thụt vào.


Cảm ơn bạn, những gì bạn đã nói đã hoạt động, bao giờ tôi muốn chỉ ra rằng mã thông báo đóng không thể được thụt lề, nếu không, nó gây ra lỗi trong bash, tôi cho rằng điều này là do nó cũng bao gồm khoảng trắng trong phần đóng.
Tristian

Lưu ý rằng Apple OS X sed không hỗ trợ đọc tập lệnh từ đầu vào tiêu chuẩn. (Ít nhất là không theo cách đó hoặc bất kỳ cách thức tài liệu nào khác.)
danorton

@danorton: Tôi đã thêm một giải pháp không cần hỗ trợ -f -trong sednhưng nó yêu cầu thay thế quy trình : <( command ).
pabouk

5

Trong trường hợp sedkhông hỗ trợ đọc của một kịch bản từ stdin(sử dụng -f -), bạn có thể sử dụng thay thế tiến trình (trong có sẵn bash, zsh, ksh93):

sed "$IN" > "$OUT" -f <( cat << SED_SCRIPT
    s/a/1/g
    s/test/full/g
SED_SCRIPT)

Dấu ngoặc đơn đóng )phải theo dấu phân cách kết thúc ( SEC_SCRIPT) ngay lập tức hoặc sau dòng mới. Trong trường hợp thay thế quy trình, bạn cũng có thể sử dụng echothay vì tài liệu ở đây:

sed "$IN" > "$OUT" -f <( echo \
"    s/a/1/g
    s/test/full/g" )

1
Trên Mac OS X, nó không giống như tệp đầu vào ( "$IN"hoặc thậm chí testfile.txt) ngay lập tức theo lệnh sed - nó muốn một -e scripthoặc -f file. Sắp xếp lại câu trả lời của @pabouk cho tôi:sed -f <( cat << ETC ... ETC) "$IN" > "$OUT"
Stephen P

Trên Max OSX với bash 4.2,45 và sed BSD tiêu chuẩn, các dấu ngoặc đơn đóng phải nằm trên một dòng mới bên dưới đóng SED_SCRIPT.
Alexander Klimetschek

-1

Có lẽ một cách tiếp cận đẹp hơn:

OUT=/dev/stdout

IN=my_in_file.txt
sed -s 's/in/out/' < $IN > $OUT
  -or-
sed -s 's/in/out/' > $OUT < $IN

IN=my_in_text
sed -s 's/in/out/' <<< $IN > $OUT
  -or-
sed -s 's/in/out/' > $OUT <<< $IN

:)


1
Thú vị, nhưng bên cạnh điểm. OP muốn truyền lệnh sed qua stdin.
muru

Cách tiếp cận này cho phép cả hai phương pháp, tại sao downvote?
Magnus

Lặp lại: "truyền lệnh sed qua stdin". Bạn trả lời không làm điều đó bằng bất kỳ phương pháp nào.
muru
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.