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