我有以下输入:
TAG1 VALUE1;TAG2 VALUE2;sometext;TAG3 VALUE3;sometext;TAG4 VALUE4;TAG5 VALUE5;sometext
TAG1 VALUE1;sometext;TAG3 VALUE3;sometext;TAG4 VALUE4;TAG5 VALUE5;sometext
TAG1 VALUE1;TAG2 VALUE2;sometext;TAG3 VALUE3;sometext;TAG4 VALUE4;TAG5 VALUE5
TAG1 VALUE1;TAG2 VALUE2;sometext;TAG3 VALUE3;sometext;TAG5 VALUE5;sometext
TAG1 VALUE1;TAG2 VALUE2;sometext;
我需要以下输出:
TAG2 VALUE2;TAG3 VALUE3;TAG5 VALUE5;
TAG3 VALUE3;TAG5 VALUE5;
TAG2 VALUE2;TAG3 VALUE3;TAG5 VALUE5;
TAG2 VALUE2;TAG3 VALUE3;TAG5 VALUE5;
TAG2 VALUE2;
或者,或者与上面相同,但只有值
我试过以下:
grep -oP '(?<=TAG2 ).*?(?=;)|(?<=TAG3 ).*?(?=;)|(?<=TAG5 ).*?(?=;)'
它有效,但每个值都在不同的行中:
VALUE2
VALUE3
VALUE5
我不能假设所有行都有所有标记,所以每一行输入我真的需要一行输出。首选本机Linux工具 - sed,awk,grep等。
谢谢!
答案 0 :(得分:2)
使用awk
:
$ awk 'BEGIN{FS=OFS=";"}{print $2, $4, $7}' file
TAG2 VALUE2;TAG3 VALUE3;TAG5 VALUE5
BEGIN{FS=OFS=";"}
将输入和输出字段分隔符设置为;
。{print $2, $4, $7}
根据该分隔符打印第2,第4和第7个字段。我希望解析键/值对的原因不是 必须存在所有键,而不一定是相同的 列(但至少它们按特定顺序存在,TAG1是 首先,TAG2下一个等...)
然后这样的事情应该成功:
awk -v values="TAG1 TAG5"
'BEGIN{split(values, vals, " ")}
{a[$1]=$2}
END{for (i in vals) print vals[i], a[vals[i]]}'
RS=";" file
-v values="TAG1 TAG5"
密码以解析要分析的值。'BEGIN{split(values, vals, " ")}
将它们存储到vals[]
数组中。{a[$1]=$2}
保存a["TAG1"] = "VAL1"
匹配。END{for (i in vals) print vals[i], a[vals[i]]}'
打印匹配。RS=";"
将记录分隔符设置为;
,以便我们可以处理文件中的几个值。示例:
$ awk -v values="TAG1 TAG3" 'BEGIN{split(values, vals, " ")} {a[$1]=$2} END{for (i in vals) print vals[i], a[vals[i]]}' RS=";" file
TAG1 VALUE1
TAG3 VALUE3
$ awk -v values="TAG1 TAG6" 'BEGIN{split(values, vals, " ")} {a[$1]=$2} END{for (i in vals) print vals[i], a[vals[i]]}' RS=";" file
TAG1 VALUE1
TAG6
答案 1 :(得分:1)
这是一种perl方式:
$ perl -ne 'print $1," " while(/(?<=TAG[235] )(.*?)(?=;)/g); print "\n";' in.txt
根据评论编辑:
$ perl -ne 'print $1," " while(/(?<=(?:DEV|SRC|DST|ACT) )(.*?)(?=;)/g); print "\n";' in.txt
在行动中:
$ cat in.txt
TAG1 VALUE1;TAG2 VALUE2;sometext;TAG3 VALUE3;sometext;TAG4 VALUE4;TAG5 VALUE5;sometext
TAG1 VALUE1;sometext;TAG3 VALUE3;sometext;TAG4 VALUE4;TAG5 VALUE5;sometext
TAG1 VALUE1;TAG2 VALUE2;sometext;TAG3 VALUE3;sometext;TAG4 VALUE4;TAG5 VALUE5
TAG1 VALUE1;TAG2 VALUE2;sometext;TAG3 VALUE3;sometext;TAG5 VALUE5;sometext
TAG1 VALUE1;TAG2 VALUE2;sometext;
$ perl -ne 'print $1," " while(/(?<=TAG[235] )(.*?)(?=;)/g); print "\n";' in.txt
VALUE2 VALUE3 VALUE5
VALUE3 VALUE5
VALUE2 VALUE3
VALUE2 VALUE3 VALUE5
VALUE2
答案 2 :(得分:0)
使用纯BASH:
l='TAG1 VALUE1;TAG2 VALUE2;sometext;TAG3 VALUE3;sometext;TAG4 VALUE4;TAG5 VALUE5;sometext'
( IFS=';' && read -a arr <<< "$l"; echo "${arr[1]}; ${arr[3]}; ${arr[6]};" )
TAG2 VALUE2; TAG3 VALUE3; TAG5 VALUE5;
IFS=';'
在将行读入数组时将分隔符设为;
。