我需要查找并替换某些文件中的某些模式,但如果未找到模式,我需要它返回 1 或其他值。
我可以单独使用 sed 执行此操作,还是需要使用另一个命令检查该模式是否存在?
有什么建议么?
答案1
看看这个答案:如何检查sed
文件是否已更改。
它与您所要求的几乎相同,它建议您使用awk
或输出到不同的文件和diff
两个文件。
答案2
Sed 按顺序处理每个模式空间的命令。如果您使用寻址来搜索好的模式,则可以使用q
sed 中的命令返回正值。
sed '/if-the-pattern-space-has-this/<do this command>' <file>
该命令结束后(在本例中以 分隔;
),将运行下一个命令(前提是您尚未通过查找上一个模式来终止。
最后一个命令$q 1
使用 sed 地址,美元符号表示该命令仅在文件的最后一行运行。如果您在文件的最后一行已经找到了好的模式,那么您就已经退出了,所以这只是作为最后的手段。如果是这种情况,那么您将返回您的负面模式。
> sed -n '/good-pattern/q 0;$q 1' <<< "bad-pattern"
> echo $?
1
> sed -n '/good-pattern/q 0;$q 1' <<< "good-pattern"
> echo $?
0
如果您使用寻址来仅查找文件区域内的模式匹配,则这可能很有用,而这是grep
很难轻松表达的内容(公平地说,sed
如果没有一些舞蹈,就不会做到这一点)。
此示例查找文件中以^block:
空行开头和结尾的部分,如果crazy
在该块中找到该单词,则返回 true:
sed -n '/^block:/,/^$/{/crazy/q 0};$q 1' <<END && echo -e "\n--------------\n FOUND" || echo "\n----------------\n NOT FOUND"
this thing
block:
is crazy
END
--------------
FOUND
^block:
该示例在to范围之外列出了“crazy”一词<empty line>
,因此返回 false。
> sed -n '/^block:/,/^$/{/crazy/q 0};$q 1' <<END && echo -e "\n--------------\n FOUND" || echo -e "\n----------------\n NOT FOUND"
this thing
block:
is crazy
END
----------------
NOT FOUND
如果您想根据是否进行了某些更改而返回正数或负数,我会推荐如下所示:
.sed 文件:substitutions.sed
# Searching for the word "crayons", replace this
# with "pizza" to see a positive match. The replacement
# word is "meanies", which you can also replace.
s/crayons/meanies/
# We print each line regardless of a pattern match
p
# If the most recent 's' command did a substitution, take
# the branch to the loop.
t loop
# If we're not on the last line, delete the pattern space and
# start processing the next line.
$!d
# This only happens on the last line. If we get here, swap the
# last hold space in and then return positive or negative based
# on the content in the hold space. The hold space should only
# have matching content if we matched once before and swapped
# the matching pattern into the hold space.
x
/meanies/q 0
# If we don't match the replacement pattern then return falsy.
q 1
# This loop is only taken on a positive match, effectively
# just swapping the most recent match into the hold space.
:loop
x
数据文件:data.txt
file has some
content, be kind pizza
don't eat pizza after 8
because of the pepperoni monsters
sed命令:
sed -nf substitutions.sed data.txt && echo -e '\nGood' || echo -e '\nBad'
请注意,sed 命令用于-n
指示每次到达 sed 脚本末尾时不会打印模式空间。 -f
表示您从以下文件中读取 sed 命令。
如果您想疯狂,您可以使用 sed 作为解释器将其包装在 shell 脚本中(使用 发现其位置which sed
)。为了简洁起见,我这次省略了注释,并将“蜡笔”替换为“披萨”作为替换模式。
外壳脚本:sed.sh
#!/usr/bin/sed -nf
s/pizza/meanies/
p
t loop
$!d
x
/meanies/q 0
q 1
:loop
x
调用:
> ./sed.sh data.txt
file has some
content, be kind meanies
don't eat meanies after 8
because of the pepperoni monsters
> echo $?
0