如何用awk小写部分文件?
How to lower case part of file with awk?
我有很多文件,其中包含诸如
之类的行
local1 = "AAA"
private = "Filename_With_Uppercase"
我想将等号的右侧改为小写。但仅适用于以 private
.
开头的行
如果我这样做
gawk -F'=' '/^private/{gsub(/[-/]/, "_"); tolower()} 1' filename
那么它不会改变任何东西...
问题
谁能弄清楚为什么等号的右边没有转换为小写?
为什么等号右边不转为小写?
Return a copy of string, with each uppercase character in the string
replaced with its corresponding lowercase character. Nonalphabetic
characters are left unchanged.
所以你需要将它分配回去以获得可见的效果,即 =tolower()
而不仅仅是 tolower()
并且还将 FS 设置为 OFS 以避免将 =
替换为
即
'BEGIN{FS=OFS="="}/^private/{gsub(/[-/]/, "_");=tolower()} 1'
你实际上必须 使用 tolower()
返回的值,它不像 [g]sub()
它修改它的参数它更像 substr()
因为它 returns 修改后的字符串,请参阅 awk 手册。
当您的文件名包含 =
符号时,任何使用 </code> 或依赖于在 <code>=
上拆分的字段的解决方案都将失败。这是使用 tag=value 对输入数据的方法:
$ cat tst.awk
{
tag = val = [=10=]
sub(/ *=.*/,"",tag)
}
tag == "private" {
sub(/[^=]+ *= */,"",val)
gsub(/[-/]/,"_",val)
[=10=] = tag " = " tolower(val)
}
{ print }
$ awk -f tst.awk file
local1 = "AAA"
private = "filename_with_uppercase"
以上假设,如您的示例中,您的输入中没有前导白色 space - 如果有,则很容易处理它。
使用您展示的示例,请尝试以下 awk
代码。
awk -F'^private = ' 'BEGIN{OFS="private = "} NF>=2{=tolower()} 1' Input_file
解释: 简单的解释就是,将^private =
作为此处所有行的字段分隔符。然后将所有行的 OFS
设置为 private =
。在主程序中,检查字段数是否大于或等于 2,然后根据要求将整个第二个字段更改为小写,然后打印 edited/non-edited 行。
由于您已经在使用 gnu awk
,因此可以在 gensub
函数中一步完成:
awk -F= '/^private/ { = gensub(/[-/]/, "_", "g", tolower())} 1' file
local1 = "AAA"
private "filename_with_uppercase"
我有很多文件,其中包含诸如
之类的行local1 = "AAA"
private = "Filename_With_Uppercase"
我想将等号的右侧改为小写。但仅适用于以 private
.
如果我这样做
gawk -F'=' '/^private/{gsub(/[-/]/, "_"); tolower()} 1' filename
那么它不会改变任何东西...
问题
谁能弄清楚为什么等号的右边没有转换为小写?
为什么等号右边不转为小写?
Return a copy of string, with each uppercase character in the string replaced with its corresponding lowercase character. Nonalphabetic characters are left unchanged.
所以你需要将它分配回去以获得可见的效果,即 =tolower()
而不仅仅是 tolower()
并且还将 FS 设置为 OFS 以避免将 =
替换为
即
'BEGIN{FS=OFS="="}/^private/{gsub(/[-/]/, "_");=tolower()} 1'
你实际上必须 使用 tolower()
返回的值,它不像 [g]sub()
它修改它的参数它更像 substr()
因为它 returns 修改后的字符串,请参阅 awk 手册。
当您的文件名包含 =
符号时,任何使用 </code> 或依赖于在 <code>=
上拆分的字段的解决方案都将失败。这是使用 tag=value 对输入数据的方法:
$ cat tst.awk
{
tag = val = [=10=]
sub(/ *=.*/,"",tag)
}
tag == "private" {
sub(/[^=]+ *= */,"",val)
gsub(/[-/]/,"_",val)
[=10=] = tag " = " tolower(val)
}
{ print }
$ awk -f tst.awk file
local1 = "AAA"
private = "filename_with_uppercase"
以上假设,如您的示例中,您的输入中没有前导白色 space - 如果有,则很容易处理它。
使用您展示的示例,请尝试以下 awk
代码。
awk -F'^private = ' 'BEGIN{OFS="private = "} NF>=2{=tolower()} 1' Input_file
解释: 简单的解释就是,将^private =
作为此处所有行的字段分隔符。然后将所有行的 OFS
设置为 private =
。在主程序中,检查字段数是否大于或等于 2,然后根据要求将整个第二个字段更改为小写,然后打印 edited/non-edited 行。
由于您已经在使用 gnu awk
,因此可以在 gensub
函数中一步完成:
awk -F= '/^private/ { = gensub(/[-/]/, "_", "g", tolower())} 1' file
local1 = "AAA"
private "filename_with_uppercase"