次のようにスペースで区切られたファイルがあります。
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 '{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,":")
a
- 2番目のフィールドを区切り文字で配列に分割します。:
答え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番目のフィールドからコロンで区切られた1番目と2番目のフィールドを抽出します$f2
。expr
これが不可能な場合は、最終的に$f2
変数自体を使用します。
Seder:
sed -e '
s/[^[:space:]]\{1,\}/\
&\
/2
:loop
s/\n\(.*:.*\):.*\n/\n\1\n/
tloop
s/\n//g
' yourfile
2番目のフィールドをで囲むことから始めて、\n
2つのフィールド(またはフィールド区切り文字)だけが残るまで、その領域の周りにループを実行します。
真珠:
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