awk:从字段中提取字符串

awk:从字段中提取字符串

输入字段中用管道符号分隔:

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()它设置RSTARTRLENGTH变量来指示匹配发生的位置,然后用于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()的功能引入:sedsawk

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

相关内容