条件付きで行を数字に置き換える

条件付きで行を数字に置き換える

約1,100万個の小さなファイルを含むディレクトリがあります。次のようになります。

wa_filtering_DP15_good_pops_snps_file_1
wa_filtering_DP15_good_pops_snps_file_2
.
.
.
wa_filtering_DP15_good_pops_snps_file_11232111

各ファイルには、以下のように2行と315列のみがあります。

1   0   0   0   0   0   0   0   0   0   1   2   1   
0   0   0   0   0   0   0   0   0   0   0   0   0

各ファイルを繰り返し、2行の各列に0の値がある場合は、それを9に置き換えて、次の結果を得ます。

1   9   9   9   9   9   9   9   9   9   1   2   1   
0   9   9   9   9   9   9   9   9   9   0   0   0

誰かが私がこれを行う方法を見つけるのを助けることができますか?ありがとう

ベストアンサー1

awk解決策は次のとおりです。

awk '{split($0,ary1,/[ ]+/); getline x; split(x,ary2,/[ ]+/); 
    for (i in ary1)if (!(ary1[i]+ary2[i])){ary1[i]=ary2[i]=9}} 
END{for (r=1;r<=NF;r++) printf ("%d ", ary1[r]); printf"\n"; 
    for (z=1;z<=NF;z++) printf ("%d ", ary2[z]); printf"\n"}' infile

説明する:

  • split($0,ary1,/[ ]+/);ary1:最初の行を読み取り、配列間に1つ以上のスペース区切り文字を使用して配列に分割します。

  • getline x; split(x,ary2,/[ ]+/);:2行目を変数として読み、配列に分割xしますary2

  • for (i in ary1)if (!(ary1[i]+ary2[i])){ary1[i]=ary2[i]=9}}: 2 つのフィールド値の合計が次の場合、配列のary1各インデックスを繰り返します。i若い(真の条件でトリガされます!(0)。) 次に、2 つのフィールドの値を次に設定します。if(1)9

  • for (r=1;r<=NF;r++) printf ("%d ", ary1[r]); printf"\n";ary1:次に各配列の最終値と次の行を印刷しますary2


約1,100万個のファイル全体に適用するには、FILENAME.out現在読み取る入力ファイル名を表すFILENAME形式に変更を保存するだけですawk

awk '{split($0,ary1,/[ ]+/); getline x; split(x,ary2,/[ ]+/); 
    for (i in ary1)if (!(ary1[i]+ary2[i])){ary1[i]=ary2[i]=9}} 
END{for (r=1;r<=NF;r++) printf ("%d ", ary1[r])>FILENAME".out"; printf"\n">FILENAME".out"; 
    for (z=1;z<=NF;z++) printf ("%d ", ary2[z])>FILENAME".out"
}' wa_filtering_DP15_good_pops_snps_file_{1..11232111}

おすすめ記事