如何仅将 awk 命令应用于特定字段

How to apply awk command to a specific field only

我在“Changing the case of a string with awk”中找到了我的问题的部分解决方案,@AndersJohansson 发布的命令是:

echo 'ABCD EFGH IJKL MNOP QRST UVWX' | awk '{for (i=1; i<=NF; ++i) { $i=toupper(substr($i,1,1)) tolower(substr($i,2)); } print }'

结束打印 Abcd Efgh Ijkl Mnop Qrst Uvwx,如预期。 但是,在我的例子中,我将数据按字段分隔,例如:ABCD EFGH; IJKL MNOP; QRST UVWX 并且我只需要将命令应用于 3r(最后一个)字段(实际上在我的数据中有 9 个字段,但为了简单起见,我把只有 3).

预期输出:ABCD EFGH; IJKL MNOP; Qrst Uvwx

Whosebug 里面有很多相关的问题,甚至有一个是我自己的问题 () ,我一个一个地试图使它们适应我的情况但没有成功,显然我的知识不够关于 awk 克服解决方案的问题,所以我将非常感谢解决此问题的任何帮助...谢谢。

也许是这样的:

echo "ABCD EFGH; IJKL MNOP; QRST UVWX" |
awk '
    BEGIN { FS = OFS = "; "}
    {
        s = "";
        n = split($NF,w,/ /);
        for(i=1; i<=n; ++i)
            s = s " " toupper(substr(w[i],1,1)) tolower(substr(w[i],2))
    }
    {$NF = substr(s,2)}
    1
'

输出:

ABCD EFGH; IJKL MNOP; Qrst Uvwx
解释:
  • FS设置为": "将使awk将行拆分为由": "分隔的字段;在当前情况下,您将获得三个字段。

  • $NF 引用最后一个字段,然后在每个 space 字符上 手动 split

  • for 循环执行 upper/lower 转换并将它们存储在字符串变量中。

  • 然后更新最后一个字段并打印整行; OFS 必须设置为与 FS 相同的值,否则 "; " 将在打印行时转换为 " "