我想使用 sed 更改一堆类似脚本中的一行。其中一些脚本实际上不包含我要更改的行。但是,sed 并没有告诉我它没有改变线路,因为它不存在。关于如何让 sed 吐出警告的任何想法? 说,我有剧本一
log export ALBET=0.155
log export ALBEG=0.218
log export RADGHGCOEF=1.0
和脚本二
log export ALBET=0.168
log export ALBEG=0.201
然后
sed -i 's/RADGHGCOEF=.*/RADGHGCOEF=2.0/' script
两者都适用于它们,但我想被告知,实际上没有包含 RADGHGCOEF 的行在脚本 2 中要更改。 谢谢!
使用这个 Perl 单行:
perl -i -pe '$found++ if s/RADGHGCOEF=.*/RADGHGCOEF=2.0/; END { warn "$ARGV: not foundn" if !$found; }' script
Perl 单行代码使用这些命令行标志:-e
:告诉 Perl 在内联中查找代码,而不是在文件中查找代码.-p
:一次循环一行输入,默认情况下将其分配给$_
。在每次循环迭代后添加print $_
.-i
:就地编辑输入文件(覆盖输入文件)。
$ARGV
:当前输入文件名。
$found++ if s/.../.../
:将$found
变量从其undef
初始值递增 1,使其现在变为 1(或更多,取决于替换发生的次数).END { ... }
:在读取整个输入文件后执行代码。if !$found
:如果替换从未发生过,则$found
在布尔上下文中false
),否则true
。
另请参阅:
perldoc perlrun
:如何执行Perl解释器:命令行开关perldoc perlvar
:Perl预定义变量
您可以使用此awk
解决方案代替sed
:
awk '{n += sub(/RADGHGCOEF=.*/, "RADGHGCOEF=2.0")} 1; END{exit !n}' file &&
echo 'search string found!' || echo 'search string not found!'
此命令将在发生替换的情况下退出1
否则它将以0
退出。
在sed
之前用grep
进行测试(如评论中建议@Sundeep)比操纵奇怪的sed
选项要好。此解决方案只是为了好玩:
你可以让sed
在找到字符串时向stdrr写入一些内容:
sed 's/RADGHGCOEF=.*/RADGHGCOEF=2.0/; /RADGHGCOEF/e echo yes >&2' script
我喜欢把它放在 stderr 上,避免在添加 .
时将其写入文件中-i
当您想test
输出时,您希望将 stderr 转换回 stdout.
将东西放在一起:
test -z "$(sed -i 's/RADGHGCOEF=.*/RADGHGCOEF=2.0/;
/RADGHGCOEF/e echo yes >&2' script 2>&1)" && echo "Nothing found"
代码片段进行所需的替换,默认输出到屏幕(最终消息打印到STDERR
)。
使用选项-i
运行脚本以进行就地替换 -perl -i script.pl file_name
use strict;
use warnings;
use feature 'say';
my $count;
while( <> ) {
chomp;
$count ++ if s/RADGHGCOEF=.*/RADGHGCOEF=2.0/;
say;
}
if( $count ) {
say STDERR "Info: replaced $count time(s)";
} else {
say STDERR "Info: nothing to replace";
}
输入文件some_data
log export ALBET=0.155
log export ALBEG=0.218
log export RADGHGCOEF=1.0
以./script.pl some_data
身份运行
log export ALBET=0.155
log export ALBEG=0.218
log export RADGHGCOEF=2.0
Info: replaced 1 time(s)
以perl -i script.pl some_data
身份运行
Info: replaced 1 time(s)