ถ้าคุณต้องการเทียบเท่าsed -i.bak
มันค่อนข้างง่าย
พิจารณาสคริปต์นี้สำหรับ GNU sed:
#!/bin/sh
# Create an input file to demonstrate
trap 'rm -r "$dir"' EXIT
dir=$(mktemp -d)
grep -v '[[:upper:][:punct:]]' /usr/share/dict/words | head >"$dir/foo"
# sed program - removes 'aardvark' and 'aardvarks'
script='/aard/d'
##########
# What we want to do
sed -i.bak -e "$script" "$dir"
##########
# Prove that it worked
ls "$dir"
cat "$dir/foo"
เราสามารถแทนที่บรรทัดที่ทำเครื่องหมายด้วย
cp "$dir/foo" "$dir/foo.bak" && sed -e "$script" "$dir/foo.bak" >"$dir/foo"
สิ่งนี้จะย้ายไฟล์ที่มีอยู่เพื่อสำรองและเขียนไฟล์ใหม่
ถ้าเราต้องการเทียบเท่า
sed -i -e "$script" "$dir" # no backup
มันซับซ้อนกว่าเล็กน้อย เราสามารถเปิดไฟล์เพื่ออ่านเป็นอินพุตมาตรฐานจากนั้นยกเลิกการเชื่อมโยงไฟล์ก่อนที่จะสั่งเอาต์พุตของ sed เพื่อแทนที่:
( cp "$dir/foo" "$dir/foo.bak"; exec <"$dir/foo.bak"; rm "$dir/foo.bak"; exec sed -e "$script" >"$dir/foo" )
เราทำสิ่งนี้ใน sub-shell เพื่อให้ stdin ดั้งเดิมของเรายังคงมีอยู่หลังจากนี้ เป็นไปได้ที่จะสลับอินพุตและสลับกลับโดยไม่ต้องแบ่งย่อย แต่วิธีนี้ดูเหมือนชัดเจนสำหรับฉัน
โปรดทราบว่าเราระมัดระวังในการคัดลอกก่อนแทนที่จะสร้างfoo
ไฟล์ใหม่ซึ่งเป็นสิ่งสำคัญหากไฟล์นั้นมีชื่อมากกว่าหนึ่งชื่อ (เช่นมีฮาร์ดลิงก์) และคุณต้องการแน่ใจว่าคุณจะไม่ทำลายลิงก์ .
/usr/gnu/bin/sed
เพื่อรับการสนับสนุน -i