如何用awk小写部分文件?

How to lower case part of file with awk?

我有很多文件,其中包含诸如

之类的行
local1 = "AAA"
private = "Filename_With_Uppercase"

我想将等号的右侧改为小写。但仅适用于以 private.

开头的行

如果我这样做

gawk -F'=' '/^private/{gsub(/[-/]/, "_"); tolower()} 1' filename

那么它不会改变任何东西...

问题

谁能弄清楚为什么等号的右边没有转换为小写?

为什么等号右边不转为小写?

tolower(string) 功能

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"