Menggunakan dokumen di sini untuk `sed` dan file

10

Saya ingin menggunakan di sini-doc untuk perintah sed dan menyediakan file untuk dibaca dan file output.

Saya telah melihat di sini-Documents dari Advanced Bash Scripting guide tetapi tidak menyebutkan apa-apa tentang argumen reguler dalam menggunakan di sini-doc. Apakah itu mungkin?

Saya ingin mencapai sesuatu seperti berikut:

#!/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;

Bantuan apa pun sangat dihargai.

Tristian
sumber

Jawaban:

14

Anda dapat memberi tahu GNU sed untuk membaca skrip dari input standar dengan -f -, -fartinya untuk membaca skrip dari file, dan -artinya input standar seperti yang umum dengan banyak perintah.

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

POSIX sed juga mendukung -f, tetapi penggunaan -untuk input standar tidak didokumentasikan. Dalam hal ini, Anda dapat menggunakan /dev/stdinsistem Linux (dan saya ingat Solaris juga memilikinya, tetapi saya tidak dapat mengonfirmasi hal itu sekarang)

Menggunakan <<-SED_SCRIPT(dengan awalan '-') akan memungkinkan SED_SCRIPTtag penutup diindentasi.

camh
sumber
Terima kasih, apa yang Anda katakan berhasil, bagaimana saya ingin menunjukkan bahwa token penutup tidak dapat diindentasi, jika tidak menyebabkan kesalahan dalam bash, saya berasumsi ini karena itu juga termasuk ruang putih di yang penutup.
Tristian
Perhatikan bahwa Apple OS X sed tidak mendukung pembacaan skrip dari input standar. (Setidaknya tidak dengan cara itu atau cara lain yang didokumentasikan.)
danorton
@danorton: Saya telah menambahkan solusi yang tidak memerlukan dukungan dari -f -dalam sedtetapi membutuhkan substitusi proses: <( command ).
pabouk
5

Dalam hal sedtidak mendukung membaca script dari stdin(menggunakan -f -), Anda dapat menggunakan proses substitusi (tersedia dalam bash, zsh, ksh93):

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

Tanda kurung penutup )harus mengikuti pembatas akhir ( SEC_SCRIPT) segera atau setelah baris baru. Dalam hal penggantian proses, Anda juga dapat menggunakan echoalih-alih dokumen di sini:

sed "$IN" > "$OUT" -f <( echo \
"    s/a/1/g
    s/test/full/g" )
pabouk
sumber
1
Pada Mac OS X, itu tidak suka file input ( "$IN"atau bahkan testfile.txt) segera mengikuti perintah sed itu sendiri - ia ingin -e scriptatau -f file. Mengatur ulang jawaban @pabouk bekerja untuk saya:sed -f <( cat << ETC ... ETC) "$IN" > "$OUT"
Stephen P
Pada Max OSX dengan bash 4.2.45 dan standar BSD, tanda kurung tutup harus berada pada baris baru di bawah penutupan SED_SCRIPT.
Alexander Klimetschek
-1

Mungkin pendekatan yang lebih baik:

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

:)

Magnus
sumber
1
Menarik, tapi selain itu intinya. OP ingin memberikan perintah sed melalui stdin.
muru
Pendekatan ini memungkinkan kedua metode, mengapa downvote?
Magnus
Ulangi: "lulus perintah sed melalui stdin". Jawaban Anda tidak melakukannya dengan metode apa pun.
muru