sed 's/foo/bar/' mylog.txt
然而,我想让搜索不区分大小写。从我谷歌到的结果来看,似乎在命令的末尾添加i
应该可以解决:
sed 's/foo/bar/i' mylog.txt
然而,这会给我一个错误信息:
sed: 1: "s/foo/bar/i": bad flag in substitute command: 'i'
这里出了什么问题,我该如何修复?
sed 's/foo/bar/' mylog.txt
然而,我想让搜索不区分大小写。从我谷歌到的结果来看,似乎在命令的末尾添加i
应该可以解决:
sed 's/foo/bar/i' mylog.txt
然而,这会给我一个错误信息:
sed: 1: "s/foo/bar/i": bad flag in substitute command: 'i'
这里出了什么问题,我该如何修复?
sed
现在支持I
标志进行不区分大小写的匹配,所以问题中的命令现在应该可以工作了(BSD sed
不会报告其版本,但您可以根据man
页面底部的日期来判断,该日期应该是2017年3月27日
或更近);以下是一个简单的示例:# BSD sed on macOS Big Sur and above (and GNU sed, the default on Linux)
$ sed 's/ö/@/I' <<<'FÖO'
F@O # `I` matched the uppercase Ö correctly against its lowercase counterpart
I
是旗帜的正式形式,但小写字母i
也可以使用。awk
现在支持本地化(awk --version
应该报告20200816
或更近的版本):# BSD awk on macOS Big Sur and above (and GNU awk, the default on Linux)
$ awk 'tolower($0)' <<<'FÖO'
föo # non-ASCII character Ö was properly lowercased
perl -C -Mutf8 -pe 's/öœ/oo/i' <<< "FÖŒ" # -> "Foo"
-C
打开流和文件的 UTF-8 支持,假设当前区域设置是基于 UTF-8 的。-Mutf8
告诉 Perl 将源代码解释为 UTF-8(在本例中是传递给 -pe
的字符串)- 这是更冗长的 -e 'use utf8;'.
的简短等效形式。感谢,Mark Reed(请注意,也不能使用 awk
,因为 macOS 上的 awk
(即 BWK awk 和 BSD awk)似乎完全不了解区域设置 - 它的 tolower()
和 toupper()
函数会忽略外来字符(而 sub()
/ gsub()
本来就没有不区分大小写的标志)。)
sed
和awk
与POSIX标准的关系的说明:sed
和awk
主要限制其功能在POSIX sed
和POSIX awk
规范所要求的范围内,而它们的GNU版本则实现了更多的扩展功能。编辑说明:该解决方案在 macOS 上(开箱即用)不起作用,因为它仅适用于 GNU 的 sed
,而 macOS 自带的是 BSD 的 sed
。
将"I"大写。
sed 's/foo/bar/I' file
sed
中,后缀 I
的用法是不可移植的。POSIX sed
仅使用基本正则表达式(BREs),其功能非常有限。它们甚至不支持 +
(必须使用 \{1,\}
替代),更不用说不区分大小写的匹配了。唯一可移植的方法是使用类似于 /[hH][eE][lL][lL][oO]/
这样的方式进行匹配,但这在实践中往往是不切实际的。 - edam/gI
,否则它只会对第一个匹配项进行操作。 - Faheem Mithased
的方法是从 MacPorts 或 HomeBrew 安装 gsed
,然后创建别名 sed='gsed'
。brew install gnu-sed
,然后进入我的~/.bash_profile
并添加了别名。感谢@davmat。 - ThinkBonobobrew install gnu-sed --with-default-names
- 这将覆盖默认的sed
。 - maroux--with-default-names
现已被弃用:brew.sh 我将 GNU sed 添加到了我的 PATH 中,但我相信现在有其他解决方法:SE question。 - FLonLon/pattern/s/xx/yy/g
然后您需要在模式后面放置 I
:
/pattern/Is/xx/yy/g
例子:
echo Fred | sed '/fred/Is//willma/g'
返回 willma
; 不带 I
, 返回原始字符串 (Fred
)。
sed: 1: "/fred/Is//willma/g": invalid command code I
- Chris F Carrollsed -r '/'"$PATTERN"'/I,${s//'$YELLOW'&'$NO_COLOR'/g;b};$q3'
。它会打印文本,如果找到模式(不区分大小写),则会用黄色(ansi颜色)突出显示文本。如果未找到,则返回退出代码3。 - Noam Manossed FAQ 解决了大小写不敏感的 搜索 相关问题。它指出,a)许多版本的 sed 支持标志,b)在 sed 中这样做很麻烦,你应该使用 awk 或 Perl。
但是,在 POSIX sed 中进行操作时,他们提供了三种选择(此处适用于替换):
Convert to uppercase and store original line in hold space; this won't work for substitutions, though, as the original content will be restored before printing, so it's only good for insert or adding lines based on a case-insensitive match.
Maybe the possibilities are limited to FOO
, Foo
and foo
. These can be covered by
s/FOO/bar/;s/[Ff]oo/bar/
To search for all possible matches, one can use bracket expressions for each character:
s/[Ff][Oo][Oo]/bar/
sed
在Mac版本中似乎有一些限制。解决方法之一是使用一个带有可用版本sed
的Linux容器(通过Docker):
cat your_file.txt | docker run -i busybox /bin/sed -r 's/[0-9]{4}/****/Ig'
sed 's/foo/bar/gI' mylog.txt
以下应该可以。
sed -i 's/foo/bar/gi' mylog.txt
tr A-Z a-z
将整个流转换为小写来处理整个内容。grep -i -l -r foo ./*
为了排除 this_shell.sh(假设你将命令放在名为 this_shell.sh 的脚本中),请将输出重定向到控制台以查看发生了什么,然后对找到的每个文件名使用 sed 将文本 foo 替换为 bar:
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结果只允许查看具有目标文本的文件(因此可能会提高性能/速度)
在使用之前,请务必备份您的文件并进行测试。对于带有嵌入空格的文件,在某些环境中可能无法正常工作。(?)
I
是GNU扩展,可能在你的sed副本中不可用。 - Lazerman sed
与实现一致-没有提到(在实践中也没有支持)大小写不敏感匹配;如果你找到了声称另外情况的文档,请告诉我们。 - mklement0g
前缀,这样当我需要使用某些在原版中没有的功能时,我就可以使用gsed
或gdate
等工具。 - Mark Reed