特定のフォルダに多数のファイルがあります。これらのファイルをサブフォルダーに移動したいのは、列4のいずれかの行に0.5を超える値が少なくとも1つある場合のみです。別のコマンドで同じことを行いますが、2行以上のファイルで上記の値を使用します。列4の0.5。
これはファイルの一般的な形式です(ヘッダー付き):
col1 col2 col3 col4 col5 col6
ABC DEF 5.10 0.94 GHI JKL
MNO PQR 8.31 0.37 STU VWX
ABC DEF 6.49 0.84 GHI JKL
MNO PQR 3.32 0.21 STU VWX
列4の一部の数値は科学表記法です:8.934553871039306e-05
以下のコードは、列4の0.5を超える値が少なくとも1つあるファイルを移動するためにこれまでに試したものです。条件に一致しないファイルも含め、すべてのファイルをサブフォルダーに移動することになります。
#!/bin/bash
find . -type f -exec awk '$4 >= 0.5' {} \; -exec mv -n {} ./NewFolder/ \;
コマンドを機能させるには、一致が見つかった場合はawk
をコード0で終了させるか、一致が見つからなかった場合はゼロ以外の終了コードで終了させる必要があります。
これに加えて、数値以外の値が文字列として比較され、予期しない一致が発生する可能性があるため、最初の行をスキップする必要があります。
find . -type f -exec awk 'FNR==1 {next} $4 >= 0.5 {found=1; exit} END {exit !found}' {} \; -exec mv -n {} ./NewFolder/ \;
注:awk
スクリプトが複数のファイルで呼び出された場合、終了コードは、いずれかのファイルで一致が見つかったことを意味します。 find
コマンドは、一度に1つのファイルのみがawk
に渡されるようにするため、ここでは問題になりません。
2番目の編集:
少なくとも2つの一致する行があるファイルを選択するには、一致をカウントできます。
find . -type f -exec awk 'FNR==1 {next} $4 >= 0.5 {found++; if(found >= 2) exit} END {exit found >= 2}' {} \; -exec mv -n {} ./NewFolder/ \;
編集:
スクリプトが列4に一致する値を持たないファイルを移動する問題をデバッグするには、コードをawk
スクリプトに追加して、一致する行に関する情報を出力します。次のコードは、一致するものが見つかった場合、ファイル名、行番号、および一致する行を出力します。
find . -type f -exec awk 'FNR==1 {next} $4 >= 0.5 {found=1; printf "%s:%d:%s\n", FILENAME, FNR, $0; exit} END {exit !found}' {} \; -exec mv -n {} ./NewFolder/ \;
次のようなものになります
threshold.txt:2:ABC DEF 5.10 0.94 GHI JKL
最初にこれを実行して、問題の原因を見つけることをお勧めします。
列4に数値以外のテキストがある行がある場合、値はテキストとして比較されます。これにより、たとえば"abc"
が"0.5"
より大きい。
別の考えられる原因は、列1または2にスペースがある行であり、列へのテキストの誤った割り当てにつながる可能性があります。
列4に数値以外の値があり、これらの行を無視したい場合は、0
のように値を0 + $4
に追加することにより、数値の解釈を強制できます。
find . -type f -exec awk 'FNR==1 {next} 0 + $4 >= 0.5 {found=1; printf "%s:%d:%s\n", FILENAME, FNR, $0; exit} END {exit !found}' {} \; -exec mv -n {} ./NewFolder/ \;
問題の理由がフィールドがタブで区切られていて、値にスペースが含まれている可能性がある場合は、フィールド区切り文字(-F "\t"
)を指定できます。次のスクリプトは、これを他の変更と組み合わせています。
find . -type f -exec awk -F "\t" 'FNR==1 {next} 0 + $4 >= 0.5 {found=1; printf "%s:%d:%s\n", FILENAME, FNR, $0; exit} END {exit !found}' {} \; -exec mv -n {} ./NewFolder/ \;
awk
は実際には機能しません。文字列col4
が>=0.5
を満たすため、すべてのファイルが検索されます。
$ echo col4 | awk '$1>=0.5'
col4
したがって、ヘッダーをスキップする必要があります。また、ファイルが基準に一致する場合は成功して終了し、一致しない場合は失敗して終了するようにawkに指示する必要があります。このようなもの:
find . -type f \
-exec awk -va=1 '{ if($4 >= 0.5 && NR>1){a=0}} END{exit a}' {} \; \
-exec mv -n {} ./NewFolder/ \;
Forループを使用すると、これを試すことができます。
for i in *; do # *.extension
[[ -f "$i" && $(awk 'NR>1 && $4 >= 0.5' "$i") ]] && mv "$i" NewFolder/
done
そして、2つの値について:
for i in *; do # *.extension
[[ -f "$i" ]] && [[ $(awk 'NR>1 && $4 >= 0.5' "$i" | wc -l) -ge 2 ]]
mv "$i" NewFolder
done