我们有一个进程可以使用包含sed
命令的文件来改变管道输入。
我需要用输入值替换输入中的占位符,例如在一个-e
类型的命令中,我可以运行;
$ echo "Today is XX" | sed -e "s/XX/$(date +%F)/"
Today is 2012-10-11
但是我只能在文件中指定sed
个方面(然后将过程指向文件),例如。名为replacements.sed
的文件可能包含;
s/XX/Thursday/
很明显;
$ echo "Today is XX" | sed -f replacements.sed
Today is Thursday
但是,如果我想使用环境变量或shell值,我找不到一种方法来扩展它,例如如果replacements.txt
包含;
s/XX/$(date +%F)/
然后;
$ echo "Today is XX" | sed -f replacements.sed
Today is $(date +%F)
在文件的文本中包含双引号只会打印双引号。
有没有人知道如何在sed
文件中使用变量?
答案 0 :(得分:7)
这可能适合你(GNU sed):
cat <<\! > replacements.sed
/XX/{s//'"$(date +%F)"'/;s/.*/echo '&'/e}
!
echo "Today is XX" | sed -f replacements.sed
如果您没有GNU sed,请尝试:
cat <<\! > replacements.sed
/XX/{
s//'"$(date +%F)"'/
s/.*/echo '&'/
}
!
echo "Today is XX" | sed -f replacements.sed | sh
答案 1 :(得分:3)
AFAIK,这是不可能的。你最好的选择是:
INPUT FILE
aaa
bbb
ccc
SH SCRIPT
#!/bin/sh
STRING="${1//\//\\/}" # using parameter expansion to prevent / collisions
shift
sed "
s/aaa/$STRING/
" "$@"
命令行
./sed.sh "fo/obar" <file path>
<强>输出强>
fo/obar
bbb
ccc
答案 2 :(得分:2)
正如其他人所说的那样,你不能在sed脚本中使用变量,但是你可以使用额外的前导输入来“伪造”它,它会被添加到你的保持缓冲区。例如:
[ghoti@pc ~/tmp]$ cat scr.sed
1{;h;d;};/^--$/g
[ghoti@pc ~/tmp]$ sed -f scr.sed <(date '+%Y-%m-%d'; printf 'foo\n--\nbar\n')
foo
2012-10-10
bar
[ghoti@pc ~/tmp]$
在这个例子中,我正在使用进程重定向来获取sed的输入。 “重要”数据由printf
生成。你可以改为使用文件,或运行其他程序。 “变量”由date
命令生成,并成为脚本的第一行输入。
sed脚本占用第一行,将其放入sed的保持缓冲区,然后删除该行。然后对于任何后续行,如果它匹配双短划线(我们的“宏替换”),它将替换保持缓冲区的内容。并打印,因为这是sed的默认操作。
保持缓冲区(g,G,h,H和x命令)代表“高级”sed编程。但是一旦你理解了它们是如何工作的,它们就开辟了sed fu的新维度。
注意:此解决方案仅可帮助您替换整行。使用保持缓冲区替换行内的子串可能是可能的,但我无法想象一种方法。
(另一个注意事项:我在FreeBSD中这样做,它使用与你在Linux中找到的不同的sed。这可能在GNU sed中有效,或者可能没有;我没有测试过。)
答案 3 :(得分:0)
我同意sputnick的意见。我不相信sed能够完成这项任务。
但是,您可以动态生成该文件。
您可以将日期更改为固定字符串,例如
__DAYOFWEEK__
。
创建临时文件,使用sed将__DAYOFWEEK__
替换为$(date +%Y)
。
然后使用sed -f $TEMPFILE
解析您的文件。
sed很棒,但是可能是时候使用像perl这样可以动态生成日期的东西了。
答案 4 :(得分:0)
要使用sed文件在替换表达式中添加换行符,最终对我有用的是转义文字换行符。示例:在字符串NewLineHere之后添加换行符,然后对我有用:
#! /usr/bin/sed -f
s/NewLineHere/NewLineHere\
/g
不确定这很重要,但是我在Solaris unix上,所以肯定不是GNU sed。