データ ファイルA.tsv
(フィールド区切り文字 = \t
) があります:
id mutation
243 siti,toto,mumu
254
267 lala,siti,sojo
289 lala
テンプレート ファイルB.txt
(フィールド区切り文字 = 1 行 1 列のみなので重要ではありません):
lala,siti,mumu
に新しい列A.tsv
(ただし、新しいファイルC.tsv
)を作成し、 のリストには存在しない、 の列mutation_not
に存在する変異だけが印刷されるようにします。mutation
A.tsv
B.txt
C.tsv
次のようになります:
id mutation mutation_not
243 siti,toto,mumu toto
254
267 lala,siti,sojo sojo
289 lala
除外を試してみました:
awk 'NR==FNR {exclude[$0];next} !($0 in exclude)' file2 file1
しかし、良い結果が出ていません。何かアイデアはありますか?ありがとうございます
答え1
awk ' BEGIN{OFS="\t"}
NR==FNR{ for(i=1; i<=NF; i++) muts[$i]; next }
FNR>1 { len=split($2, tmp, ",");
for(i=1; i<=len; i++) buf= buf (tmp[i] in muts?"":(buf==""?"":",") tmp[i])
}
{ print $0, (FNR==1?"mutation_not":buf); buf="" }' FS=',' fileB FS='\t' fileA
答え2
使用方法gawk
:
awk 'BEGIN{OFS="\t"; }
NR==FNR{ar[$1]=$1;next}
FNR==1{$(NF+1) = "mutation_not"}
FNR>1{split($2,a,",");
for(i in a) if (a[i] in ar) ;
else ncol[$1] = (ncol[$1])? ncol[$1] "," a[i] : a[i];
$(NF+1) = ncol[$1]}1'
RS="," B.txt RS="\n" FS="\t" A.tsv
すべてのフィールドがカンマで区切られ、1 行のみであると仮定すると、RS
ファイルの Record Separator( ) はカンマに設定されますB.txt
。
NR==FNR{ar[$1]=$1;next
ar
最初のファイルの最初のフィールドでインデックス付けされた配列を作成します。
FNR==1{$(NF+1) = "mutation_not"
ヘッダー名にもう 1 つの列を作成します。
FNR>1{split($2,a,",")
の 2 番目のフィールドをA.tsv
配列に分割しますa
。
に存在しない次のエントリは配列B.txt
に保存されますncol
。
$(NF+1) = ncol[$1]
配列の要素を含むもう 1 つの列を作成しますncol
。
答え3
set
ファイルB.txtのコンマ区切りの要素からs2を作成します。
次に、A.tsv の各行の 2 番目のフィールドをセットに変換し、そこから s2 セットを減算します。これにより、B.txt にはない A.tsv に存在する変異が取得されます。次に、結果の要素を結合し、元の行とともに出力します。
python3 -c 'import sys
tsv,txt = sys.argv[1:]
fs,rs = "\t","\n"
ofs,dlm = fs,","
with open(txt) as fh, open(tsv) as f:
s2 = set(*list(map(lambda x:x.rstrip(rs).split(dlm),fh.readlines())))
for nr,ln in enumerate(f,1):
l = ln.rstrip(rs)
if nr == 1: print(l,"mutation_not",sep=ofs)
else:
F = l.split(ofs)
if len(F) < 2: print(l)
else: print(l,
dlm.join({*F[1].split(dlm)}-s2),sep=ofs)
' A.tsv B.txt
結果:
id mutation mutation_not
243 siti,toto,mumu toto
254
267 lala,siti,sojo sojo
289 lala
今回は、Gnu sed エディタを使用して結果を取得します。
sed -Ee '
1{h;d;}
2s/\tmutation$/&&_not/;t
s/\t\S+$/&&,/;T;G
s/\t/\n/2;ta
:a
s/\n([^,]+),(.*\n(.*,)?\1(,|$))/\n\2/;ta
s/\n([^,\n]+),/\t\1\n/;ta
s/\n.*//
' B.txt A.tsv
アイデアとしては、Btxt ファイルが保持され (1 行であると想定)、A.tsv の各行に B.txt の内容が追加され、B.txt で見つかった変異にチェックが付けられます。すべての変異が確認された後、行が印刷されます。