该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
如果要省略模式空间的默认打印,则替换q
为Q
(请注意,这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