假设一个多行文本文件file
,其中一些行以空格开头。
$ cat file
foo Baz
baz QUX
QUx Quux
BaZ Qux
BazaaR
进一步假设我希望将所有那些以关键字开头的行(例如" baz ")转换为小写字母,无论是否(a)该关键字被写入用小写或大写字母(或其任何组合)本身,以及(b)该关键字以空格开头。
$ cat file | sought_command
foo Baz # not to lowercase (line does not start with keyword)
baz qux # to lowercase
QUx Quux
baz qux # to lowercase
BazaaR # not to lowercase (line does not start with keyword, but merely with a word containing the keyword)
我相信 awk 是这样做的工具,但我不确定如何为关键字匹配实现不区分大小写。
$ cat file | awk '{ if($1 ~ /^ *baz/) print tolower($0); else print $0}'
foo Baz
baz qux
QUx Quux
BaZ Qux # ERROR HERE: was not replaced, b/c keyword not recognized.
BazaaR
编辑1 :
添加IGNORECASE=1
似乎可以解决不区分大小写的问题,但现在错误地将最后一行转换为小写。
$ cat file | awk '{IGNORECASE=1; if($1~/^ *baz/) print tolower($0); else print $0}'
foo Baz
baz qux
QUx Quux
baz qux
bazaar # ERROR HERE: should not be converted to lowercase, as keyword not present (emphasis on word!).
答案 0 :(得分:3)
您已经了解tolower()
所以只需在比较中再次使用它并测试精确的字符串匹配而不是部分正则表达式:
awk 'tolower($1)=="baz"{$0=tolower($0)}1'
答案 1 :(得分:1)
在搜索字符串后添加字边界
$ awk '{IGNORECASE=1; if($1~/^ *baz\>/) print tolower($0); else print $0}' ip.txt
foo Baz
baz qux
QUx Quux
baz qux
BazaaR
可以重写为:
awk 'BEGIN{IGNORECASE=1} /^ *baz\>/{$0=tolower($0)} 1' ip.txt
由于使用了线锚,因此无需与$1
匹配。最后的1
将打印记录,包括所做的任何更改
IGNORECASE
和\>
具有gawk
个特定功能。 \y
也可用于匹配字边界
使用GNU sed
$ sed 's/^[[:blank:]]*baz\b.*/\L&/I' ip.txt
foo Baz
baz qux
QUx Quux
baz qux
BazaaR
[[:blank:]]
将匹配空格或制表符\L&
将小写行\b
是字边界I
标记以区分大小写