vcfファイルがたくさんあります
HR001.vcf
HR002.vcf
HR003.vcf
HR004.vcf
HR005.vcf
HR006.vcf
HR007.vcf
HR008.vcf
.
.
内部に列10各ファイルの列ヘッダーは$ iです。各ファイルで$ iをファイルのデフォルト名に変更したいと思います。たとえば、ファイルHR001.vcfの場合は$i = HR001、HR002.vcfの場合は$i = HR002など... Unixでこれを行う簡単な方法はありますか?私はMacBook Proを所有していますが、これに精通していません。これは、実際にはタブ区切りフィールドを持つVCFファイルです。はい、スキップする必要があるファイルごとに236行があります。 #CHROM で始まる行に興味があります。つまり、237行、237行の10列に$iが含まれています。
答え1
私は以下を使用しますperl
:
perl -F'\t' -i -lape '
if ($F[0] eq "#CHROM" && $F[9] eq q($i)) {
$F[9] = ($ARGV =~ s/\.vcf$//r);
$_ = join "\t", @F
}' -- *.vcf
答え2
次のスクリプトが操作を実行します。
cd /path/to/direcrtory
for i in *.vcf
do
awk '{if (FNR==1) $10=FILENAME; print}' "$i" >"$i.tmp" && mv -f "$i.tmp" "$i"
done
「マジック」は入力ファイル名を含むFILENAME
変数にあります。awk
答え3
答え4
ファイルがスペースで区切られていると仮定すると、次のように動作します。
for f_name in HR[0-9]*.vcf; do
awk -v f="${f_name%.*}" 'NR == 1 {$10 = f}1' "$f_name" > "$f_name.tmp"
mv "$f_name.tmp" "$f_name"
done
ディレクトリを繰り返して各vcf
ファイルをインポートします。次に、ファイル名から拡張子を削除し${f_name%.*}
て引数として渡しますawk
。
awk
変更時にファイル名として使用されます。ノート:ファイルと同じディレクトリで実行する必要がありますvcf
。別のパスで実行するには、次のコマンドを使用します。
for f_name in /some/full/path/HR[0-9]*.vcf; do
# remove the path
f="${f_name##*/}"
awk -v f="${f%.*}" 'NR == 1 {$10 = f}1' "$f_name" > "$f_name.tmp"
mv "$f_name.tmp" "$f_name"
done
ファイルがスペースで区切られていない場合に修正されましたawk FS
。
@Ed Mortonの改善に基づいて新しいリクエストに合わせて編集
#CHROM で始まる行に興味があります。つまり、237行、237行の10列に$iが含まれています。
for f_name in /some/full/path/HR[0-9]*.vcf; do
# remove the path
f="${f_name##*/}"
awk -F'\t' -v f="${f%.*}" 'NR == 237 {$10 = f}1' "$f_name" > "$f_name.tmp" && mv "$f_name.tmp" "$f_name"
done
($10 = f)
この新しいバージョンのスクリプトは、必要なフィールドと目的の行のファイル名のみを置き換えます(NR == 237)
。このawk
パラメータは、行が表示されフィールド間で分割される-F\t
方法を設定します。awk
元のスクリプトを改善した@Ed Mortonにもう一度感謝します。説明が示すように、以下は、1行に圧縮されたmv "$f_name.tmp" "$f_name"
新しいファイル(によって生成された)の内容で古いファイルを上書きするコマンドです。コマンドが失敗した場合、右側の部分は実行されず、元のデータは安全に保たれます。awk
awk '' file > tmp && mv tmp file
awk
&&