次のような多くの行を含むタブ区切りのファイルがあります。
1 ILM-rs199 info1 info2 info3
2 aws-rs2778 info4 info5 info6
3 345-678945 info7 info8 info9
4 aws-rs789 info10 info11 info-rs789
2番目と4番目の列を抽出したいです。 2番目の列では、次のようにrsで始まる文字列とそれに続く数字だけが必要です。
rs199 info2
rs2778 info5
rs789 info11
以下を使用して2番目の列のみを抽出できました。
egrep -o 'rs[0-9]*' filename
与えられた
rs199
rs2778
rs789
しかし、他の熱も維持する必要があるときに詰まった。
awkでegrepを使用しようとしています(2番目の列のrs番号を抽出するために)完了できません。
答え1
$ # assuming `rs[digits]` string will match only in 2nd column
$ # string matched within () will get printed
$ perl -lne 'print /(rs\d+\t)[^\t]+\t([^\t]+)/' ip.txt
rs199 info2
rs2778 info5
$ # to match from 2nd column only
$ perl -lne 'print /^[^\t]+\t[^\t]*(rs\d+\t)[^\t]+\t([^\t]+)/' ip.txt
rs199 info2
rs2778 info5
$ # to get some other column, say 2nd and 5th
$ perl -lne 'print /^[^\t]+\t[^\t]*(rs\d+\t)(?:[^\t]+\t){2}([^\t]+)/' ip.txt
rs199 info3
rs2778 info6
一致するものがある場合にのみ印刷します。
$ perl -lne '/^[^\t]+\t[^\t]*(rs\d+\t)(?:[^\t]+\t){1}([^\t]+)/ && print $1,$2' ip.txt
rs199 info2
rs2778 info5
$ perl -lne '/^[^\t]+\t[^\t]*(rs\d+\t)(?:[^\t]+\t){2}([^\t]+)/ && print $1,$2' ip.txt
rs199 info3
rs2778 info6
抽出する文字列が互いに隣接している以前のソリューション
$ # assuming the shell being used supports $'' strings
$ grep -o $'rs[0-9]*\t[^\t]*' ip.txt
rs199 info1
rs2778 info4
答え2
以下はいくつかのオプションです。
アッ
$ awk -vOFS="\t" '{sub(/.*-/,"",$2);print $2,$4}' file rs199 info1 rs2778 info3
これにより、2番目のフィールドの最初のフィールドの前のすべての内容が削除され、
-
結果の2番目と4番目のフィールドが印刷されます。真珠
$ perl -pe 's/.*?-*(rs\d+\t)\S+\t(\S+).*/$1\t$2/' file rs199 info2 rs2778 info5
上記のように、最初のフィールドにそのエントリを含めることができると
rs
失敗します。より強力なアプローチは次のとおりです。$ perl -F'\t' -lane '$F[1]=~s/.+-//; print join "\t",@F[1,3]' file rs199 info2 rs2778 info5
これにより、2番目のフィールドのすべての前の文字が削除され
-
(2番目のフィールドに文字がない場合は何も実行されません-
)、2番目と4番目のフィールドが印刷されます。
答え3
私は次の方法でそれをしました
入力ファイル
ILM-rs199 info1 info2 info3
aws-rs2778 info4 info5 info6
345-678945 info7 info8 info9
aws-rs789 info10 info11 info-rs789
注文する
awk -F "-" '{print $1,$2,$3,$4,$5}' inputfile | awk '$2 ~ /^rs[0-9]/{print $2,$4}'
出力
rs199 info2
rs2778 info5
rs789 info11