我正在尝试使用SED从日志文件中提取文本。
我可以毫不费力地进行搜索和替换:
sed 's/foo/bar/' mylog.txt
但是,我想让搜索不区分大小写。从我用Google搜索的内容看起来,将i
附加到命令的末尾应该可以正常工作:
sed 's/foo/bar/i' mylog.txt
但是,这给了我一条错误消息:
sed: 1: "s/foo/bar/i": bad flag in substitute command: 'i'
这里出了什么问题,我该如何解决?
我在使用macOS,以防万一。
答案 0 :(得分:63)
要明确:在 macOS - 从Mojave(10.14)开始 - sed
- 这是 BSD 实施 - 不支持案例 - 敏感匹配 - 很难相信,但却是真的。由于评论中提到的基于sed
的解决方案,formerly accepted answer本身显示了 GNU perl
命令,因此获得了该状态。
要使 Perl解决方案与外国字符一起使用,通过UTF-8,请使用以下内容:
perl -C -Mutf8 -pe 's/öœ/oo/i' <<< "FÖŒ" # -> "Foo"
-C
会启用对流和文件的UTF-8支持。-Mutf8
告诉Perl将源代码解释为UTF-8(在这种情况下,传递给-pe
的字符串) - 这是更短的等价物详细-e 'use utf8;'.
谢谢,Mark Reed (请注意使用awk
不是的选项,而是macOS上的awk
(即 BWK awk ,又名 BSD awk )似乎完全没有意识到语言环境 - 它的tolower()
和toupper()
函数忽略了外来字符(并且sub()
/ gsub()
没有案例 - 开始的 - 不敏感标志)。)
答案 1 :(得分:59)
编者注::此解决方案不适用于macOS(开箱即用),因为它仅适用于 GNU sed
,而macOS附带 BSD sed
。
将'我'大写。
sed 's/foo/bar/I' file
答案 2 :(得分:23)
Mac OS X上define('YII_DEBUG', false);
的另一种解决方法是从MacPorts或HomeBrew安装sed
,然后创建别名gsed
。
答案 3 :(得分:2)
sed FAQ解决了紧密相关的不区分大小写的 search 。它指出:a)许多版本的sed支持它的标志,b)在sed中这样做很尴尬,您应该使用awk或Perl。
但是要在POSIX sed中做到这一点,他们建议了三种选择(此处适用于替代):
转换为大写并将原始行存储在保留空间中;但是,这对于替换无效,因为原始内容将在打印之前恢复,因此仅适用于基于不区分大小写的匹配项插入或添加行。
也许可能性仅限于FOO
,Foo
和foo
。这些可以通过
s/FOO/bar/;s/[Ff]oo/bar/
要搜索所有可能的匹配项,可以为每个字符使用方括号表达式:
s/[Ff][Oo][Oo]/bar/
答案 4 :(得分:1)
sed
的Mac版似乎有点受限。解决此问题的一种方法是使用具有可用版本sed
的Linux容器(通过Docker):
cat your_file.txt | docker run -i busybox /bin/sed -r 's/[0-9]{4}/****/Ig'
答案 5 :(得分:0)
我有类似的需求,并想出了这个:
这个命令只是找到所有文件:
grep -i -l -r foo ./*
这个要排除this_shell.sh(如果你将命令放在一个名为 this_shell.sh 的脚本中),请将输出发送到控制台以查看发生了什么,然后在每个上使用sed找到的文件名用文本替换文本foo:
grep -i -l -r --exclude "this_shell.sh" foo ./* | tee /dev/fd/2 | while read -r x; do sed -b -i 's/foo/bar/gi' "$x"; done
我选择了这种方法,因为我没有为未修改的文件更改所有时间戳。提供grep结果只允许查看带有目标文本的文件(因此也可能提高性能/速度)
务必备份您的文件&amp;使用前测试。对于具有嵌入空格的文件,可能无法在某些环境中使用(?)
答案 6 :(得分:0)
如果您首先进行模式匹配,例如
/pattern/s/xx/yy/g
然后你想把I
放在模式之后:
/pattern/Is/xx/yy/g
示例:
echo Fred | sed '/fred/Is//willma/g'
返回willma
;如果没有I
,则返回未触及的字符串(Fred
)。
答案 7 :(得分:0)
使用以下命令替换所有出现的内容: sed的s / foo / bar / gI mylog.txt
答案 8 :(得分:-2)
sed 's/string1/string2/Ig'
Capital I
是一个选项,对于搜索字符串非常有用,无论区分大小写。