[英]find string in file and add content with bash and sed
I'm trying to add a string with a bunch of filenames (which include directory slashes) to a file after a specific search string. 我正在尝试在特定搜索字符串之后将包含一堆文件名(包括目录斜杠)的字符串添加到文件中。
I've created my input text like this: 我已经创建了这样的输入文本:
for f in /tmp/et/*.rules; do
#STRING+=`basename "$f"`$'\n';
STRING+=$'include $RULE_PATH/et/'`basename "$f"`$'\n'
done
Which makes $STRING
equal: 这使
$STRING
相等:
include $RULE_PATH/et/emerging-activex.rules
include $RULE_PATH/et/emerging-attack_response.rules
include $RULE_PATH/et/emerging-botcc.portgrouped.rules
include $RULE_PATH/et/emerging-botcc.rules
include $RULE_PATH/et/emerging-chat.rules
include $RULE_PATH/et/emerging-ciarmy.rules
include $RULE_PATH/et/emerging-compromised.rules
include $RULE_PATH/et/emerging-current_events.rules
include $RULE_PATH/et/emerging-deleted.rules
include $RULE_PATH/et/emerging-dns.rules
and my sed
command to add the $STRING
content looks like this: 和我添加
$STRING
内容的sed
命令如下所示:
sed -i.bak 's!^#EMERGING\ THREATS\ RULESET.*$!& \n'"$STRING"'!' snort.conf
this is looking for the text #EMERGING THREATS RULESET
and adding $STRING
on a new line after the matched text. 这是寻找文本
#EMERGING THREATS RULESET
并在匹配的文本后在新行上添加$STRING
。
I had to change the default sed
delimiters to something else because the default /
were conflicting with the directory paths in my $STRING
. 我必须将默认的
sed
分隔符更改为其他内容,因为默认/
与$STRING
的目录路径冲突。 Now, the problem is that I'm getting an error from sed
stating: 现在,问题是我从
sed
说出错:
sed: -e expression #1, char 82: unterminated `s' command
I know this has gotta be a simple problem with string manipulation or something regarding the quotes, but I've tried lots of combinations here and can't figure it out... 我知道这必须是一个简单的字符串操作问题或关于引号的东西,但我在这里尝试了很多组合,无法弄清楚...
Ok use this approach: 好的,使用这种方法:
#!/bin/bash
> _tmp
for f in /tmp/et/*.rules; do
echo $'include $RULE_PATH/et/'`basename "$f"`$'\n' >> _tmp
done
sed -i.bak '/^#EMERGING THREATS RULESET/r _tmp' snort.conf
Which basically stores your output in a temporary file and uses that temporary file to replace content in sed command after your search pattern. 这基本上将您的输出存储在临时文件中,并使用该临时文件在搜索模式后替换sed命令中的内容。
You are using incorrect delimiter:
您使用的分隔符不正确:
sed -i.bak 's!^#EMERGING\\ THREATS\\ RULESET.*$/& \\n'"$STRING"'!' snort.conf ^ | ---------------------------------------------
So it seems your issue is unescaped newline. 所以看来你的问题是未转义的新行。 You cannot have an unescaped newline in
sed
replacement text ( $STRING
in your example). 您不能在
sed
替换文本中使用未转义的换行符(在您的示例中$STRING
)。 sed
scripting uses the newline just like the shell does, to terminate a command. sed
脚本使用新行就像shell一样,终止命令。
If you need a newline in the replacement text, you need to precede it with a backslash. 如果在替换文本中需要换行符,则需要在其前面加上反斜杠。 Alternatively, if you're using
gnu sed
and do not care about portability to other sed implementations, you can replace a newline with a \\n
, in the replacement text (all posix-compliant seds allow this in the regular expression, but not in the replacement as it is a gnu extension). 或者,如果您正在使用
gnu sed
并且不关心其他sed实现的可移植性,则可以在替换文本中用\\n
替换换行符(所有符合posix标准的seds都允许在正则表达式中使用,但不能在替换,因为它是gnu扩展)。 Since your embedded newline is in a variable, this approach will not work for you. 由于您的嵌入式换行符在变量中,因此这种方法不适用于您。
So you can either do as @anubhava has shown in his answer, or alternatively use an awk
solution: 所以你可以像@anubhava在他的回答中所做的那样,或者使用
awk
解决方案:
awk -v patt="$STRING" '/^#EMERGING THREATS RULESET/{print $0;print patt;next}1' snort.conf >tmp && mv tmp snort.conf
Not that this would need GNU awk
. 并不是说这需要
GNU awk
。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.