我有一个名为"insert.txt“的文件。它可能看起来像这样(或者更丑陋):
ASDFG?|??|?\/\HJKL<MNBVCXZQWERTYUIOP
zxvbnmlkjhgfdsaqwertyuiop
123"'`~4567890987654321!@#$%^&*()
@#$%^&*()+_}{":?>我想要将目标文件(target.txt)中由"STARTSTACKOVERFLOW“分隔的文本块替换为"STOPSTACKOVERFLOW”。(我在这里稍微简化了这个问题,但它是一样的)。
我用来执行此操作的bash脚本是:
TARGETFILE=target.txt
SOURCEFILE=insert.txt
SOURCETXT="$(<$SOURCEFILE)"
DELIMTXT=$(printf "%q" "$SOURCETXT")
sed -i -e "/STARTSTACKOVERFLOW/,/STOPSTACKOVERFLOW/cSTARTSTACKOVERFLOW\n\n${DELIMTXT}\n\nSTOPSTACKOVERFLOW\n" $TARGETFILE问题是粘贴到"target.txt“中的内容实际上是ANSI-C引用的:
$'ASDFG?|??|?\/\HJKL<MNBVCXZQWERTYUIOP
zxvbnmlkjhgfdsaqwertyuiop
123"'`~4567890987654321!@#$%^&*()
@#$%^&*()+_}{":?>'请注意添加了$'‘。
原因是printf "%q“产生了这种引用样式。我想要避免这种情况-尽管我需要它,因为我必须避开这个文件中的所有坏处。
有没有更好的方法来使用bash和sed来完成上面的工作?
发布于 2010-10-27 02:31:22
POSIX sed有一个'r‘命令来读取文件。所以:
sed -i -e '/STARTSTACKOVERFLOW/,/STOPSTACKOVERFLOW/r large.txt' target.txt唯一的问题是文件是读取一次,还是在开始行和停止行之间每行读取一次。我怀疑每个line...and都会读一次,解决如何去掉多余的行可能是harder...but:
sed -i -e '/STOPSTACKOVERFLOW/r large.txt' \
-e '/STARTSTACKOVERFLOW/,/STOPSTACKOVERFLOW/d' target.txt简单的演示
此版本删除了开始和结束标记。
$ cat data
sdasas
adsasdas
start
more
more
end
sdasda
sdasdad
$ cat replace
replace1
replace2
replace3
$ sed -e '/^end$/r replace' -e '/start/,/end/d' data
sdasas
adsasdas
replace1
replace2
replace3
sdasda
sdasdad保留开始标记和结束标记
$ cat sedfile
/^end$/{
a\
start
r replace
a\
end
}
/^start$/,/^end$/d
$ sed -f sedfile data
sdasas
adsasdas
start
replace1
replace2
replace3
end
sdasda
sdasdad
$ 这很麻烦-如果不使用脚本的文件,我不会尝试这样做,但如果您愿意的话,您可以这样做。不过,这不是一行。
https://stackoverflow.com/questions/4026652
复制相似问题