指定された列のヘッダーをファイル名に置き換えます

指定された列のヘッダーをファイル名に置き換えます

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

ここに画像の説明を入力してください@YetAnotherUser、私のリクエストに関するサンプルファイルの画像をご覧ください: 「特定の列のヘッダーをファイル名に置き換える」

答え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に再度感謝します。ご覧のとおり、ステートメント :mv "$f_name.tmp" "$f_name"は、古いファイルを新しいファイルの内容 ( によって生成されたもの) で上書きするコマンドでありawk、1行に凝縮されています。awk '' file > tmp && mv tmp fileこのようにして、awkコマンドが失敗した場合、 の適切な部分は&& 実行されず、元のデータは安全に保持されます。

関連情報