Вы делаете это правильно, но синтаксис bash легко неправильно истолковать :вы можете подумать, что echo $TEST
заставляет echo
извлекать TEST
env var, а затем печатать его, но это не так. Так дано
export TEST=123
, затем
TEST=456 echo $TEST
включает следующую последовательность:
Оболочка анализирует всю командную строку и выполняет все подстановки переменных, поэтому командная строка становится
TEST=456 echo 123
Он создает временные переменные, установленные перед командой, поэтому сохраняет текущее значение TEST
и перезаписывает его на 456; командная строка теперь
echo 123
Он выполняет оставшуюся команду, которая в данном случае выводит 123 на стандартный вывод (, поэтому оставшаяся команда оболочки даже не использовала временное значениеTEST
)
Восстанавливает значениеTEST
Вместо этого используйте printenv, так как он не требует подстановки переменных:
>> export TEST=123
>> printenv TEST
123
>> TEST=456 printenv TEST
456
>> printenv TEST && TEST=456 printenv TEST && TEST=789 printenv TEST && printenv TEST
123
456
789
123
>>
Чтобы ваша команда работала, вы должны 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
обеспечивает передачу только одного файла за раз в 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
И для двух значений:
for i in *; do # *.extension
[[ -f "$i" ]] && [[ $(awk 'NR>1 && $4 >= 0.5' "$i" | wc -l) -ge 2 ]]
mv "$i" NewFolder
done