【问题标题】:Combining multiple awk commands with different delimiters将多个 awk 命令与不同的分隔符组合起来
【发布时间】:2023-03-22 20:24:01
【问题描述】:

我连续运行两个awk 命令以根据多个分隔符分解字符串。我想知道它们是否可以组合成一个命令。

输入数据(jot -w "some string, this is number " 10):

some string, this is number 1
some string, this is number 2
some string, this is number 3
some string, this is number 4
some string, this is number 5
some string, this is number 6
some string, this is number 7
some string, this is number 8
some string, this is number 9
some string, this is number 10

这只是示例数据,但我希望能够先根据逗号拆分字符串,然后从第二部分中提取数字(第四个单词)。实际上,字符串第一部分中的空格数可能会有所不同,即以下内容将是有效输入:

some string, this is number 1
some string with more spaces, this is number 2

以下命令可以正常工作:

$ jot -w "some string, this is number " 10 | awk -F ',' '{print $2}' | awk -F ' ' '{print $4}'
1
2
3
4
5
6
7
8
9
10

有没有什么简单的方法可以将这两个命令组合成一个命令?

【问题讨论】:

  • awk 将正则表达式作为分隔符,但如果逗号之前的部分可以有不同数量的字段,则可能需要运行两个 awks。也许您可以将cut 用于“更简单”的部分?
  • @jasper cut 绝对是一个选项,谢谢,是的,我知道awk 可以使用正则表达式作为分隔符,但即使空格数之前没有变化逗号,执行两个连续的 awk 语句(在我的应用程序中)比必须更改第二个程序中的字段索引更具可读性。不过感谢您的评论。
  • AWK multiple delimiter的可能重复

标签: awk


【解决方案1】:

您可以使用 NF 轻松打印最后一列

jot -w "some string, this is number " 10 |awk '{print $NF}'

或者按照你的想法,将两个 awk 合二为一。

jot -w "some string, this is number " 10  |awk '{l=split($2,a,OFS);print a[l]}' FS="," 

【讨论】:

    【解决方案2】:

    split() 函数可以让你这样做:

    awk '{split($0,a,",");split(a[2],b," ");print b[4];}'
    

    【讨论】:

    • +1,但可能应该明确说明通常会写:awk '{split($2,a," "); print a[4]}' FS=, 并使用正常的字段拆分作为第一个分隔符。
    【解决方案3】:

    解决你描述的问题是:

    $ cat file
    some string, this is number 1
    some string with more spaces, this is number 2
    
    $ awk -F, '{n=split($NF,a,/ /); print a[n]}' file
    1
    2
    

    或者如果你喜欢高尔夫:

    $ awk -F, '{print a[split($NF,a,/ /)]}' file
    1
    2
    

    但显然使用您指定的输入会起作用:

    $ awk '{print $NF}' file
    1
    2
    

    与其他各种解决方案一样。

    【讨论】:

    • 既然这个答案被接受了,那我就得给点建议了。 / / 的split功能在大多数情况下都可以,但并非总是如此,建议更改为OFS(因为FS已被使用并设置为其他值。)
    • split 的第三个参数是一个字段分隔符,它是一个对单个空白字符 " " 进行特殊处理的正则表达式。因此,为了清晰和功能,RE 常量的正确分隔符是/.../ 的 RE 分隔符(例如,如果您使用字符串分隔符 "...",那么您需要双重转义任何 RE 元字符以将它们视为文字)。使用输出字段分隔符拆分输入只是因为它碰巧被设置为您想要 split() 输入的相同字符,这只是不必要的耦合和混淆。
    猜你喜欢
    • 1970-01-01
    • 2016-05-03
    • 2020-08-17
    • 2018-09-08
    • 1970-01-01
    • 1970-01-01
    • 2016-10-27
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多