awkを使用して各行の最初の2つの部分を抽出する

awkを使用して各行の最初の2つの部分を抽出する

次のようなスペース区切りのファイルがあります:

0   22:16050847:T:C 0   16050847
0   rs62224609:16051249:T:C 0   16051249
0   22:16051250:G:A 0   16051250
0   GSA-rs138295790 0   16057310

最初の 2 つの部分だけを抽出するように 2 番目の列を変更するにはどうすればよいですか? 出力は次のようになります。

0   22:16050847 0   16050847
0   rs62224609:16051249 0   16051249
0   22:16051250 0   16051250
0   GSA-rs138295790 0   16057310

答え1

短いawkアプローチ:

awk '{split($2,a,":"); $2=(length(a)>1)? a[1]":"a[2] : $2}1' file

出力:

0 22:16050847 0 16050847
0 rs62224609:16051249 0 16051249
0 22:16051250 0 16051250
0 GSA-rs138295790 0 16057310

  • split($2,a,":")- 2番目のフィールドをaセパレータで配列に分割します:

答え2

GNU awkをお持ちの場合:

gawk '{split($2,a,/[:-]/,c); $2 = sprintf("%s%c%s", a[1], c[1], a[2])} 1' file
0 22:16050847 0 16050847
0 rs62224609:16051249 0 16051249
0 22:16051250 0 16051250
0 GSA-rs138295790 0 16057310

答え3

perl

perl -lpe 's/^\S+\s+[^:]+:[^:]+\K\S+//' file

GNUの場合sed:

sed -E ':t s/:\w+//2; tt' file

出力:

0   22:16050847 0   16050847
0   rs62224609:16051249 0   16051249
0   22:16051250 0   16051250
0   GSA-rs138295790 0   16057310

答え4

バッシュ:

while read -r f1 f2 rest; do
   printf '%s' "$f1" "$(expr " $f2" : '\([^:]*:[^:]*\).*' \| " $f2")" "$rest"; echo
   # the lone echo provides for the newline
done < yourfile

readはフィールドを$f1、に分割し$2、残りはすべて にまとめられます$rest。次に、2 番目のフィールド で を実行し$f2exprコロンで区切られた最初のフィールドと 2 番目のフィールドを抽出します。これが不可能な場合は、変数自体を使用することになります$f2

セド:

sed -e '
   s/[^[:space:]]\{1,\}/\
&\
/2
   :loop
      s/\n\(.*:.*\):.*\n/\n\1\n/
   tloop
   s/\n//g
' yourfile

まず 2 番目のフィールドを で囲み\n、次に 2 つのフィールド (または 1 つのフィールド区切り文字) だけが残るまでこの領域の周りをループします。

パール:

perl -pe 's/\G[^:\h]+:[^:\h]+\K\S+//,next while /\S\h+\S/g' yourfile

perl -pe 's/^\h*\S+\h+(?:(?!:)\S)+:(?:(?!:)\S)+\K\S+//' yourfile

perl -F'(\h+)' -lane '
   /:/ and $_ = join ":", (/[^:]+/g)[0,1] for $F[/^\h/?4:2];
   print @F;
' yourfile

結果

0   22:16050847 0   16050847
0   rs62224609:16051249 0   16051249
0   22:16051250 0   16051250
0   GSA-rs138295790 0   16057310

関連情報