ディレクトリ内のすべてのファイルを繰り返したいです。
ファイルの設定は次のとおりです。
<Overall>4
other data
<Overall>2
other data
......
コードがあります。
for file in .dat;
do
awk 'x+=sub(/<Overall>/,""){y+=$0} END{print FILENAME, y/x}' $file
done
これはファイル内の値の平均を出力しますが、私が望むのは、スクリプトを含むディレクトリを引数として取得し、ディレクトリ内のすべての.datファイルに対してawkコマンドを実行することです。
コードを試してみました。
for file in $1
しかし、エラーが発生しました。
awk: cmd. line:1: fatal cannot open file `folder' for reading (No such file or directory)
これに加えて、平均出力を高レベルから低レベルにソートしたいと思います。
答え1
2つのバリエーション:
- ファイルを繰り返し、
awk
各ファイルに対して1回呼び出すか、 - スクリプトに
awk
すべてのファイルを提供し、各ファイルの平均を計算し、実行時に報告するようにします。
出力をパイピングして、次のソリューションの結果を並べ替えることができます。
sort -k2,2rn
2番目のフィールド(平均)に対して逆方向の数値ソートを実行します。
最初の回避策:
#!/bin/sh
for name in "$1"/*.dat; do
test -f "$name" || continue # skip non-files
awk -F '>' '/<Overall>/ { s+=$NF; n++ } END { print FILENAME, s/n }' "$name"
done
スクリプトには、最初と唯一のコマンドライン引数としてコマンドラインのディレクトリ名が必要です。スクリプトawk
は、文字列を含むすべての行を見つけ、その行Overall
(in)の後の値を合計します。最後に、平均値がファイル名とともに出力されます。この変数は、私たちが何かを追加した回数を保持します。s
>
n
s
2番目の回避策(GNU Awkが必要):
#!/bin/sh
find "$1" -maxdepth 1 -type f -name '*.dat' \
-exec awk -F '>' '/<Overall>/ { s+=$NF; n++ } ENDFILE { print FILENAME, s/n; s=n=0 }' {} +
最初のスクリプトと同様に、このスクリプトには唯一のコマンドライン引数としてディレクトリ名が必要です。一度にできるだけ多くのファイルを含むスクリプトをfind
実行するために使用されます。awk
.dat
スクリプトawk
はGNU Awkのトリガーを使用して計算された値を出力し、ENDFILE
各ファイルを処理してから次のファイルを読み始める前にs
変数をリセットします。n
これは次のように書くこともできます。
#!/bin/sh
awk -F '>' '/<Overall>/ { s+=$NF; n++ } ENDFILE { print FILENAME, s/n; s=n=0 }' "$1"/*.dat
ただし、これは"$1"/*.dat
あまりにも長いファイル名のリストに拡張しないことに依存します(これを行うには、各名前が上記のコマンドで保証される.dat
通常のファイルである必要があります)。find
-type f