输入字段中用管道符号分隔:
CCCC|Sess C1|s1 DA=yy07:@##;/u/t/we
DDDDD|Sess C2|s4 DB=yy8:@##;/u/ba
我想获得最后一个字段更改的输出(仅提取该字段中第一个 = 和 : 之间的内容
预期输出是:
CCCC|Sess C1|yy07
DDDDD|Sess C2|yy8
答案1
标准awk
不太擅长根据模式从字段中提取数据。一些选项包括:
split()
根据指定的分隔符将文本拆分为数组。match()
它设置RSTART
和RLENGTH
变量来指示匹配发生的位置,然后用于subtr()
提取匹配的部分。
所以在这里:
awk -F'|' -v OFS='|' '
split($3, a, /[=:]/) >= 2 {print $1, $2, a[2]}' < file.txt
=
因此返回第一次和第二次出现 a或:
in之间的部分$3
。
或者:
awk -F'|' -v OFS='|' '
match($3, /=[^:]*/) {
print $1, $2, substr($3, RSTART+1, RLENGTH-1)
}' < file.txt
GNUawk
有一个扩展,它将's命令gensub()
的功能引入:sed
s
awk
gawk -F'|' -v OFS='|' '
$3 ~ /=/ {
print $1, $2, gensub(/^[^=]*=([^:]*).*/, "\\1", 1, $3)
}' < file.txt
查找 后面=
跟着任意数量的非:
s 并提取 后面的部分=
。问题gensub()
是您无法轻易判断替换是否成功,因此首先检查$3
包含=
。
和sed
:
sed -n 's/^\([^|]*|[^|]*|\)[^=|]*=\([^:|]*\).*/\1\2/p' < file.txt
和perl
:
perl -F'[|]' -lane 'print "$F[0]|$F[1]|$1" if $F[2] =~ /=([^:]*)/' < file.txt
答案2
我会尝试
awk -F\| 'BEGIN {OFS="|";}
{col=index($3,":");
equ=index($3,"=");
$3=substr($3,equ+1,col-equ-1);
print ; }' se
在哪里
-F\|
告诉 awk 用作|
输入分隔符equ=index($3,"=");
获取第三个字段中 = 的索引$3=substr($3,equ+1,col-equ-1);
进行实际替换
答案3
第一个子删除字段 3 中的前第六个字符,第二个子删除冒号之后的所有字符(包括)。
awk -F\| '{sub(/.{6}/,"",$3)sub(/:.*/,"")}1' OFS=\| file