複数のファイルから列の最小値を検索し、別のファイルに出力します。

複数のファイルから列の最小値を検索し、別のファイルに出力します。

次のようなファイル1があります

25       104.601  0.5 
24.8488  104      0.5 
24.5341  103      0.5 
24.1844  102      0.5 
24.1568  101      0.5 
24.1568  100      0.5 
24.1844  99       0.5 
24.5341  98       0.5 

列 1 から最小値を見つけて別のファイルに印刷する必要があります_NEW

ここで、異なるファイルに対して上記を繰り返し、少なくとも 100 個のファイルの最小値を見つける必要があります。

こうすることで、file_NEWに次のような最終出力が出力されます。

24.1568
23.3254 (from file2)
22.312  (from file3)
.....

ここで、file2とfile3はfile1と同様のデータセットを持っています。すべての入力ファイルはfile*.txtのような同じ名前パターンを持ち、同じディレクトリにあります。

awk または sed でこれを行う方法を提案できる人はいますか?

ありがとう

答え1

最小値を見つけるには、以下のコマンドを使用します。

各ファイルに対して以下のコマンドを使用します

awk 'NR==1{sum=$1}($1 < sum){sum=$1}END{print sum}'  filename >> outputfile

テスト済みで問題なく動作しました

答え2

awk '{print $1 "\t(from " FILENAME ")"}' file* | sort -k1,1n | awk -F'\t' '!seen[$2]++'

上記は、標準的な UNIX ツールを使用して、すべての入力ファイルに対して一度に堅牢かつ効率的に動作します。例:

$ cat file1
25       104.601  0.5
24.8488  104      0.5
24.5341  103      0.5
24.1844  102      0.5
24.1568  101      0.5
24.1568  100      0.5
24.1844  99       0.5
24.5341  98       0.5

$ cat file2
75       104.601  0.5
74.8488  104      0.5
74.5341  103      0.5
74.1844  102      0.5
74.1568  101      0.5
74.1568  100      0.5
74.1844  99       0.5
74.5341  98       0.5

$ awk '{print $1 "\t(from " FILENAME ")"}' file{1,2} | sort -k1,1n | awk -F'\t' '!seen[$2]++'
24.1568 (from file1)
74.1568 (from file2)

ただし、ファイル名にタブ文字や改行文字が含まれていないことを前提としています。タブが含まれている場合は、簡単な調整で処理できます。

awk '{print $1 "\t(from " FILENAME ")"}' file* |
sort -k1,1n |
awk '{f=$0; sub(/[^\t]*\t/,"",f)} !seen[f]++'

\0ただし、改行も含まれている場合は、 (NUL) 終端文字に対応するために GNU ツールが必要になります。

awk -v ORS='\0' '{print $1 "\t(from " FILENAME ")"}' file* |
sort -z -k1,1n |
awk -v RS='\0' '{f=$0; sub(/[^\t]*\t/,"",f)} !seen[f]++'

答え3

バージョンsed

find . -name "file*" -exec sh -c '
   echo $(sort -nk1 "$1"  | sed -n "1{s/ .*//p}" )" (from "${1##*/}")" ' sh {} \; | sort -nk1 > output.txt; cat output.txt

sort必要に応じて出力ファイルを編集し、ファイル名を追加する

答え4

私の理解では、各ファイルにこれが必要です:

awk 'NF' FILE | sort -n -k1 - | awk 'NR==1{print $1}' >> file_NEW

awk 'NF' FILE入力ファイルに空白行がある場合、先頭にが必要です。このコマンドを特定のディレクトリ内のすべてのファイルに対して再帰的に実行するか、非再帰的に実行するか、または名前に特定のパターンを持つ一部のファイルに対してのみ実行するかを指定しませんでした。とにかく、find次のようにして実行できます。

find . -name "FILE*" -exec sh -c 'awk "NF" FILE | sort -n -k1 - | awk "NR==1{print \$1}" >> file_NEW' sh {} \;

この場合、上記のコマンドは、指定されたディレクトリ内で名前が で始まるすべてのファイルに対して実行されますFILE

また、これは、見つかった各ファイルに対して以降のすべてを盲目的に実行するfile_NEWので、必ずしも出力にソートされたリストが生成されるわけではないことに注意してください。find-exec

関連情報