以下はサンプルテキストファイルです。
A B C D E F G
1 2 3 4 5 6 7
2 3 4 5 6 7 8
3 4 5 6 7 8 9
3行目の値である2 3 4 5 6 7 8に基づいて特定の列を抽出したいと思います。 3行目で5より大きい値を持つすべての列を抽出したいとします。最後の3列になります。したがって、私の目標は、以下を選択して生成することです。
E F G
5 6 7
6 7 8
7 8 9
これは私のコードです。
NR==3 {
for (i=1; i<=NF; i++) {
if ($i > 5) x[j++] = i
}
}
NR>= 1 {
for (i=0 ; i < j-1; i++ )
printf("%s ",$x[i])
printf("%s\n",$x[j-1])
}
ただし、これにより次のような結果が得られます。
A B C D E F G
1 2 3 4 5 6 7
6 7 8
7 8 9
私が逃したものは何ですか?
答え1
次のことができます。
code=$(
awk '
NR == 3 {
for (i=1; i<=NF; i++)
if ($i > 5) { printf "%s", sep "$" i; sep="," }
exit sep == ""
}' file
) &&
awk "{print $code}" file
つまり、awk
同じファイルから2回呼び出すことです。最初の行は3行目を読み、2番目の呼び出しのawk
コードを構成します。 3行目を処理した後に終了するため、ファイル全体を完全に読み取ることはありません。次の結果が出力されるため、次の$5,$6,$7
呼び出しawk
は次のようになります。
awk '{print $5,$6,$7}' file
答え2
共有する別のawkソリューションがあります。
cat > extract.columns.awk
BEGIN {
infil=ARGV[1]
while (getline < infil > 0)
if (++n==3)
{
for(i=1;i<=NF;i++)
if ($(i) > 5) x[++j]=i
}
close(infil)
}
{
for (i=1;i<j;i++)
printf("%s ",$x[i])
printf("%s\n",$x[j])
}
awk -f extract.columns.awk ファイル
答え3
以下のコードに従ってファイル名を2回参照してください。
awk 'NR == FNR{if(FNR == line) {for(i=1; i<=NF; i++) {if($i > lmt) a[i]} close(FILENAME)} next}
{for(i=1; i<=NF; i++) {for(i in a) {out = (out == "") ? $i : (out FS $i)}}
print out; out=""}' line=3 lmt=5 file file