使用 sed 命令时如何获取退出状态?

使用 sed 命令时如何获取退出状态?

grep命令给出退出状态:

$echo "foo.bar" | grep -o foo
foo
$echo $?
0
$echo "foo.bar" | grep -o pop
$echo $?
1  

但我需要使用sed并且我意识到它没有退出状态:

$echo "foo.bar" | sed 's/bar.*$//'
foo.
$echo $?
0
$echo "foo.bar" | sed 's/pop.*$//'
foo.bar
$echo $?
0  

我知道我应该尝试一下这个-q选项,但我还没有成功。

答案1

您可以使用 qn以退出状态退出n- 但为了使其有用,你还需要使用一些分支和流控制

仅当自读取最后一行输入或采取另一个条件分支以来命令成功时,才有条件地分支
(即跳转到标签) 。s///

最好选择一个值n与标准退出状态值之一不同:

退出状态为零表示成功,非零值表示失败。GNU“sed”返回以下退出状态错误值:

0
 Successful completion.

1
 Invalid command, invalid syntax, invalid regular expression or a
 GNU 'sed' extension command used with '--posix'.

2
 One or more of the input file specified on the command line could
 not be opened (e.g.  if a file is not found, or read permission is
 denied).  Processing continued with other files.

4
 An I/O error, or a serious processing error during runtime, GNU
 'sed' aborted immediately.

例如

$ echo "foo.bar" | sed 's/bar.*$//; t; q42' ; echo $? 
foo.
0

然而

$ echo "foo.bar" | sed 's/baz.*$//; t; q42' ; echo $? 
foo.bar
42

如果要省略模式空间的默认打印,则替换qQ(请注意,这Q是一个 GNU 扩展)。

答案2

以下是使用 sed 搜索正则表达式的方法,以及突出比赛, 或者返回退出代码(5)如果没有找到匹配项:

这是输入.txt:

hello there
my dear old friend
a lot of things
we'll pass along the end

这是我的功能:打印全部+突出显示匹配项+返回退出代码:

highlight()
{
  pattern=$1
  shift
  sed '/'"${pattern}"'/,${s//\x1b[32m&\x1b[0m/g;b};$q5' "$@"
}

$ highlight “lo\|end” input.txt || echo -e “\n* 未找到匹配项 *”

赫尔
亲爱的老朋友结尾
A我们将
通过ng结尾

如果没有匹配,它将返回退出代码 (5)。你可以与 cat 和 pipe 一起使用 |以及:

$ cat input.txt | 突出显示“hot\|and”|| echo -e“\n* 未找到匹配项 *”

你好,
我亲爱的老朋友,
很多事情
我们会传递到最后

* 未找到匹配项 *

谢谢https://unix.stackexchange.com/a/405725/43233- 我正在使用它+ sed 退出选项。

答案3

答案重复https://stackoverflow.com/a/61808364/10440128

#!/bin/sh

read -d '' input <<EOF
a
b
EOF

echo "replace yes:"
echo "$input" >input.txt
sed -i 's/a/x/ w /dev/stdout' input.txt

echo "replace no:"
echo "$input" >input.txt
sed -i 's/z/x/ w /dev/stdout' input.txt

输出:

replace yes:
x
replace no:

因此,要检查 sed 是否替换了某些内容:

#!/bin/sh

read -d '' input <<EOF
a
b
EOF

echo "$input" >input.txt
if [ -z "$(sed -i 's/a/x/w /dev/stdout' input.txt)" ]
then echo "replace no" # -z = "zero string"
else echo "replace yes"
fi

echo "$input" >input.txt
if [ -n "$(sed -i 's/z/x/w /dev/stdout' input.txt)" ]
then echo "replace yes" # -n = "nonzero string"
else echo "replace no"
fi

输出:

replace yes
replace no

限制:只能处理一次替换。所以这不起作用:

sed -i 's,a,b, w /dev/stdout ; s,b,a, w /dev/stdout' input.txt

错误:

sed: couldn't open file /dev/stdout ; s,b,a, w /dev/stdout: No such file or directory

(sed 将后面的所有内容w视为文件路径)

解决方法:使用多个 sed 调用

#!/bin/sh

read -d '' input <<EOF
a
b
EOF

echo "$input" >input.txt
if [ -n "$(
  sed -i 's/a/x/w /dev/stdout' input.txt &&
  sed -i 's/x/a/w /dev/stdout' input.txt
)" ]
then echo "replace yes"
else echo "replace no"
fi

相关内容