ใช้ here-doc สำหรับ `sed 'และไฟล์


10

ฉันต้องการใช้ here-doc สำหรับคำสั่ง sed และจัดเตรียมไฟล์ที่จะอ่านและไฟล์เอาต์พุต

ฉันดูที่นี่ - เอกสารจากคู่มือการสคริปต์การทุบตีขั้นสูง แต่ไม่ได้พูดถึงสิ่งใดเกี่ยวกับอาร์กิวเมนต์ปกติในการใช้ here-doc เป็นไปได้ไหม

ฉันต้องการบรรลุสิ่งต่อไปนี้:

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

ความช่วยเหลือใด ๆ ที่เป็นที่นิยมจริงๆ

คำตอบ:


14

คุณสามารถบอก GNU sed อ่านสคริปต์จากการป้อนข้อมูลมาตรฐาน-f -, -fความหมายในการอ่านสคริปต์จากไฟล์และ-ความหมายเข้ามาตรฐานราวกับเป็นเรื่องธรรมดาที่มีจำนวนมากของคำสั่ง

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

POSIX sed รองรับ-fเช่นกัน แต่การใช้-สำหรับอินพุตมาตรฐานไม่ได้รับการบันทึกไว้ ในกรณีนี้คุณสามารถใช้/dev/stdinกับระบบ Linux ได้ (และฉันดูเหมือนจะจำได้ว่า Solaris มีเช่นนี้ แต่ฉันไม่สามารถยืนยันได้ในตอนนี้)

การใช้<<-SED_SCRIPT(พร้อมคำนำหน้า '-') จะอนุญาตให้SED_SCRIPTเยื้องแท็กปิด


ขอบคุณสิ่งที่คุณพูดว่าทำงานได้ยังไงฉันอยากจะชี้ให้เห็นว่าโทเค็นการปิดไม่สามารถเยื้องมิฉะนั้นจะทำให้เกิดข้อผิดพลาดในการทุบตีฉันคิดว่านี่เป็นเพราะมันรวมถึงพื้นที่สีขาวในการปิด
เตียน

โปรดทราบว่า Apple OS X ไม่รองรับการอ่านสคริปต์จากอินพุตมาตรฐาน (อย่างน้อยไม่ได้อยู่ในลักษณะนั้นหรือเอกสารอื่น ๆ )
danorton

@danorton: ผมได้เพิ่มวิธีการแก้ปัญหาที่ไม่ต้องการการสนับสนุนของ-f -ในแต่ต้องเปลี่ยนตัวกระบวนการ:sed <( command )
pabouk

5

ในกรณีที่sedไม่สนับสนุนการอ่านสคริปต์จากstdin(ใช้-f -) คุณสามารถใช้กระบวนการทดแทน (ในที่มีอยู่bash, zsh, ksh93):

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

วงเล็บปิด)จะต้องเป็นไปตามตัวคั่นท้าย ( SEC_SCRIPT) ทันทีหรือหลังบรรทัดใหม่ ในกรณีของการทดแทนกระบวนการคุณสามารถใช้echoแทนเอกสารที่นี่:

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

1
บน Mac OS X ก็ไม่ชอบใส่ไฟล์ ( "$IN"หรือแม้กระทั่งtestfile.txt) ทันทีหลังจากคำสั่ง sed ตัวเอง - มันต้องการหรือ-e script -f fileการจัดเรียงคำตอบของ @pabouk อีกครั้งทำงานให้ฉัน:sed -f <( cat << ETC ... ETC) "$IN" > "$OUT"
สตีเฟ่น P

ต่อ Max OSX กับทุบตี 4.2.45 และ BSD มาตรฐาน sed ที่วงเล็บปิดSED_SCRIPTจะต้องมีในบรรทัดใหม่ด้านล่างปิด
Alexander Klimetschek

-1

อาจเป็นวิธีที่ดีกว่า:

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
ที่น่าสนใจ แต่นอกเหนือจากประเด็น OP ต้องการส่งคำสั่ง sed ผ่าน stdin
muru

วิธีนี้ช่วยให้ทั้งสองวิธีทำไม downvote?
แมกนัส

ทำซ้ำ: "ส่งคำสั่ง sed ผ่าน stdin" คุณตอบว่าไม่ได้ทำด้วยวิธีใด ๆ
muru
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.