如果找不到模式,是否有选项使 sed 失败?

如果找不到模式,是否有选项使 sed 失败?

我需要查找并替换某些文件中的某些模式,但如果未找到模式,我需要它返回 1 或其他值。

我可以单独使用 sed 执行此操作,还是需要使用另一个命令检查该模式是否存在?

有什么建议么?

答案1

看看这个答案:如何检查sed文件是否已更改

它与您所要求的几乎相同,它建议您使用awk或输出到不同的文件和diff两个文件。

答案2

Sed 按顺序处理每个模式空间的命令。如果您使用寻址来搜索好的模式,则可以使用qsed 中的命令返回正值。

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

相关内容