从每一行中提取子字符串。这些子字符串以逗号分隔,“名称=值”格式

从每一行中提取子字符串。这些子字符串以逗号分隔,“名称=值”格式

我的文件中有以逗号分隔的行。没有列标题,主要是逗号分隔的“名称=值”对。以下是一些测试数据:

listoffruits,producelist,APPLE=red,BANNANA=yellow,GRAPE=purple,ORANGE=orange,FRUIT=yes,WATERMELON=green
listoffruits,producelist,APPLE=red,BANNANA=yellow,GRAPE=violet,ORANGE=orange,FRUIT=affirmative,WATERMELON=green

我想获取 GRAPE=* 和 FRUIT=* 的值以获得结果:

purple yes
violet affirmative

此外,我希望以后能够添加更多“列”(因此不总是葡萄、水果,而是葡萄、水果和西瓜)

另一个障碍是柱子不是固定的。所以我并不总是知道西瓜是最后一栏。

我得到的最接近的是来自@jasonwryan:

awk -v RS="," -F= '/GRAPE/{a=$2}; /FRUIT/{b=$2} END{print a,b"\n"}'

但这输出最后一行“紫罗兰肯定”而不是:

purple yes

violet affirmative

答案1

多一些选择。为了简单起见,我已保存您的示例文本file

  1. grep和 PCRE:

    $ grep -oP '(GRAPE|FRUIT)=\K.*?(?=,)' file 
    purple
    yes
    violet
    affirmative
    

    为了让它们在同一行,只需解析即可。例如

    $ grep -oP '(GRAPE|FRUIT)=\K.*?(?=,)' | paste -d" " - - –  
    purple yes
    violet affirmative
    
  2. sed

    $ sed 's/.*GRAPE=\([^,]*\).*FRUIT=\([^,]*\).*/\1 \2/' file 
    purple yes
    violet affirmative
    

    或者,使用 GNUsed

    $ sed -r 's/.*GRAPE=([^,]*).*FRUIT=([^,]*).*/\1 \2/' file 
    purple yes
    violet affirmative
    
  3. Perl

    $ perl -pne 's/.*GRAPE=([^,]*).*FRUIT=([^,]*).*/\1 \2/' file 
    purple yes
    

    您可能会注意到上面的内容与上面的内容略有相似sed:)。或者:

    $ perl -lne '@f=(/(?:(?<=GRAPE=)|(?<=FRUIT=))(.+?),/g); print "@f"' file 
    purple yes
    violet affirmative
    

    这用作,字段分隔符并搜索所有字段:

    $ perl -F, -lane '@r=grep(s/.+?=//, grep(/GRAPE|FRUIT/,@F)); print "@r"' file 
    purple yes
    violet affirmative
    

    这个较短,但为每行添加了一个前导空格:

    $ perl -F, -lane 'print grep(s/.+?=/ /, grep(/GRAPE|FRUIT/,@F));' file 
     purple yes
     violet affirmative
    

答案2

使用awk:

awk -v RS="," -F= '/GRAPE/||/FRUIT/ {printf "%s ", $2}'

将记录分隔符从换行更改为,,将字段分隔符从空格更改为=,然后匹配包含模式的行GRAPEFRUIT并在同一行上打印第二个匹配字段,并以空格分隔。结果:

purple yes 

相关内容