入力フィールドはパイプ記号で区切られています:
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
標準のawk
は、パターンに基づいてフィールドからデータを抽出することはあまり得意ではありません。いくつかのオプションが含まれます:
split()
は、指定された区切り文字に基づいてテキストを配列に分割します。match()
は、RSTART
およびRLENGTH
変数を設定して、一致が発生した場所を示し、subtr()
を使用して、一致した部分を抽出します。だからここに:
_awk -F'|' -v OFS='|' '
split($3, a, /[=:]/) >= 2 {print $1, $2, a[2]}' < file.txt
_
したがって、_=
_の_:
_または_$3
_の最初と2番目の出現の間の部分を返します。
または:
_awk -F'|' -v OFS='|' '
match($3, /=[^:]*/) {
print $1, $2, substr($3, RSTART+1, RLENGTH-1)
}' < file.txt
_
GNU awk
には、sed
のs
コマンドの機能をawk
に組み込むgensub()
拡張機能があります。
_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
_
やってみる
_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番目のフィールドの=のインデックスを取得$3=substr($3,equ+1,col-equ-1);
実際の置換を行います最初のサブはフィールド3の最初の6番目の文字を削除し、2番目のサブはコロンを含むすべてを削除します。
awk -F\| '{sub(/.{6}/,"",$3)sub(/:.*/,"")}1' OFS=\| file