在sed-f中使用变量(其中sed脚本位于文件中而不是内联)

在sed-f中使用变量(其中sed脚本位于文件中而不是内联),sed,Sed,我们有一个进程,它可以使用一个包含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 -

我们有一个进程,它可以使用一个包含
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值,我无法找到使其展开的方法,例如,If
replacements.txt
contains

s/XX/$(date +%F)/
然后,

在文件文本中包含双引号只是打印双引号


有人知道在
sed
文件中使用变量的方法吗?

好吧,这是不可能的。您的最佳选择是:

输入文件

aaa
bbb
ccc
./sed.sh "fo/obar" <file path>
SH脚本

#!/bin/sh

STRING="${1//\//\\/}"   # using parameter expansion to prevent / collisions

shift

sed "
s/aaa/$STRING/
" "$@"
fo/obar
bbb
ccc
命令行

aaa
bbb
ccc
./sed.sh "fo/obar" <file path>

我同意斯普特尼克的观点。我不相信sed能够完成这项任务

但是,您可以动态生成该文件

您可以将日期更改为固定字符串,如
\uuuuuuuuwek\uuuuuuuuuu

创建一个临时文件,使用sed将
\uuuu DAYOFWEEK\uuuu
替换为
$(日期+%Y)

然后使用
sed-f$TEMPFILE
解析文件


sed很好,但是现在可能是时候使用perl之类的工具来动态生成日期了。

正如其他人所说的,您不能在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]$ 
[ghoti@pc~/tmp]$cat scr.sed
1{;h;d;}/^--$/G
[ghoti@pc~/tmp]$sed-f scr.sed这可能适合您(GNU-sed):


cat要使用sed文件在替换表达式中添加换行符,最终对我有效的方法是转义文字换行符。示例:若要在字符串NewLineHere后追加一个新行,则此操作适用于我:

#! /usr/bin/sed -f
s/NewLineHere/NewLineHere\
/g

我不确定这是否重要,但我使用的是Solaris unix,因此不能确定是否使用GNU

请注意,如果
$STRING
包含您的分隔符(例如
/
),此操作将失败。Genius-我不理解它,但它可以工作!(我使用的是GNU sed版本)。这确实非常聪明,尽管每次使用都需要重新生成脚本。@ghoti
替换。sed
包含文本
“$(日期+%F”“
只有当脚本运行并且shell通过标志
e
或通过管道传输到shell
|sh
调用时,日期才会通过
echo
命令进行插值。啊,对了。对于非GNU建议,您可能需要在
}
之前添加分号,以便在repl中添加新行。”使用sed文件的acement表达式,最终对我有效的是转义一个文字换行符。例如:在字符串NewLineHere后附加一个换行符,这对我有效,但uu.实际上是一个文字换行符bc,因此注释不允许空白行lol:
s/NewLineHere/NewLineHere\
\ucode>/g
。我将此作为答案发布为了清楚起见,谢谢。是的,我有一个perl版本正在运行(解决方案可以是perl或sed文件),但是数据通过管道从一个可以有c500k记录的文件中输入到命令中。使用一个简单的perl脚本需要40分钟以上的时间,所以我希望sed能够提供一个更快的解决方案。
#! /usr/bin/sed -f
s/NewLineHere/NewLineHere\
/g