简体   繁体   English

在文件中查找字符串并使用bash和sed添加内容

[英]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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM