A_bla.csv
(例:など...)などの複数のファイルがありますB_bla.csv
C_bla.csv
(これは実際のファイルのソートサブサンプルですが、開くことは実際です)。
1,test,test2,55.2,test3
1,test,test2,96.3,test3
1,test,test2,64.2,test3
1,test,test2,97.2,test3
と基本ファイルmain.tsv
(フィールド区切り記号= \t
):
id coverage clade
A wrongdata 20
B wrongdata 19
C wrongdata 19
*_bla.csv
coverage
各ファイルの4列、89行のフィールドをファイル列に印刷したいと思いますmain.tsv
。これを行うには、*_bla.csv
ファイルのFILENAMEを使用し、それをid
ファイル列のパターンとして使用する必要がありますmain.tsv
。
これまで私は次のことを試しました。
for file in *_bla.csv ; do
r="$(basename -s "_bla.csv" $file)"
awk ... ;
done
しかし、今すぐ答えを始めましょう。 Linuxシステムに組み込まれているツール(awk、grep、sed、python、perl...)のみを使用してこれを行う方法をご存知ですか?ありがとう
答え1
避けられないGNUsed
ライン:
sed '1n;h;s/\([[:alnum:]]\).*/sed -E "89!d;s_([^,]*,){3}__;s_,.*__" \1_bla.csv/e;G;s/\(.*\)\n\(.*\)wrongdata/\2\1/' main.tsv
魔法は何ですか?e
代替コマンドのxecuteオプションを使用し、別のコマンドを使用してs
89行目の4番目のフィールドを抽出します。sed
詳細:
1n
最初の行は変更せずに残します。h
混乱する前に予約済みのスペースに行を保存してください\([[:alnum:]]\).*
行全体を一致させ、交換時に\(\)
参照できるように、最初の英数字フィールドをキャプチャします。\1
sed -E "89!d;s_([^,]*,){3}__;s_,.*__" \1_bla.csv
代替方法は次のとおりです。 89以外のすべての行が削除され、最初の3つのd
フィールドが削除され、最後に新しい最初のフィールド以降のすべての項目が削除されます。したがって、実際には89行の4番目のフィールドだけが残っているため、e
バッファの実行によってこのフィールドが返されます。- これで、ストレージスペースにストレージラインを追加して
G
抽出されたフィールドに置き換えることができますs/\(.*\)\n\(.*\)wrongdata/\2\1/
。wrongdata
答え2
awk -F',|\t' '
FILENAME != "main.tsv" && FNR == 89 {
sub(/_.*$/, "", FILENAME)
A[FILENAME]=$4
}
FILENAME != "main.tsv" {next}
A[$1] {$2 = A[$1]}
{print}
' *bla.csv OFS='\t' main.tsv
ファイルにタブ区切り文字がありませんmain.tsv
。次に、パターンを次のように変更する必要があります。-F',|[[:blank:]]+'
答え3
awkユーティリティを使用してこれを実行できます。 csvファイルがあるディレクトリで実行する必要があります。
awk -v OFS='\t' '
FS=="," && FNR==89 {
split(FILENAME, a, "_")
h[substr(a[1],3)] = $4
}
f=FS=="\t" {
$2 = FNR>1&&($1 in h) ? h[$1] : $2
};f
' FS=, ./*_bla.csv FS="\t" ./main.tsv
id coverage clade
A 35.8 20
B 65.7 19
C 35.8 19
perl -F, -lane '
if (@ARGV) {
89..89 && do{
$h{($ARGV=~/^..(\w+)_/)[0]} = $F[3];
close ARGV;
};
} else { #last file here
@F = split "(\t)";
$F[2] = $h{$F[0]} // $F[2];
print($.>1?@F:$_)
}
' ./*_bla.csv ./main.tsv
GNU sed。ただし、最初に各CSVファイルの89行目、フィールド4を特定し、sed s / / /ステートメントのRHSを安全に挿入できるように表示されるデータをエスケープします。
hold=$(
grep -Pzo '^(?:.*\n){88}(?:[^,]*,){3}\K[^,]*' -- *_bla.csv |
tr '\0' '\n'|
sed -Ee '
s/_.*:/\t/
s:[\&/]:\\&:g
$!s:$:\\:
')
sed -En \
-e "1{x;s/.*/$hold/;x;}" \
-e '
1!G
s/^(\S+\t)wrongdata(\t.*)\n\1([^\n]*)/\1\3\2/
P
' \
./main.tsv
python3 -c '
import sys, pathlib, itertools
mainf = sys.argv[1]
fs,rs = ofs,ors = "\t","\n"
d,dlm = {},","
for p in pathlib.Path(".").glob("*_bla.csv"):
if p.is_file():
id = p.name[:p.name.find("_")]
with open(p.name) as f:
d[id] = [l.rstrip(rs).split(dlm)[3] for l in itertools.islice(f,88,89)][0]
with open(mainf) as f:
for l in f:
L = l.rstrip(rs).split(fs)
print(L[0], d.get(L[0],L[1]), *L[2:], sep=ofs)
' ./main.tsv