2016-12-19 10 views
1

После команды find.find -iname не работает в скрипте

find Work/Linux4/test/test/test_goal/spyglass_reports/clock-reset/Ac_coherency06/ -iname "Ac_coherency*.csv" 

работает нормально при работе на раковине. Но в perl-скрипте он ничего не возвращает.

#!/bin/bash 

REPORT_DIR=$1 
FIND_CMD=$2 

echo "@@"; 
echo $REPORT_DIR ; 
echo $FIND_CMD ; 

LIST_OF_CSV=$(find $REPORT_DIR $FIND_CMD) 
echo $LIST_OF_CSV 

if [ "X" == "X${LIST_OF_CSV}" ]; then 
    echo "No files Found for : '$FIND_CMD' in directory "; 
    echo " '$REPORT_DIR' " | sed -e 's;Work/.*/test_reports;Work/PLATFORM/test_reports;g'; 
    echo; 
    exit 0; 
fi 

Выход сценария:

@@ 
Work/$PLATFORM_SPECIES/test_reports/clock-reset/Ac_coherency06 -iname "Ac_coherency06*.csv" 

No files Found for : '-iname "Ac_coherency06*.csv"' in directory  'Work/PLATFORM/test_reports/clock-reset/Ac_coherency06' 
+2

Вы используете относительный путь, выполняете ли вы скрипт из хорошего места?Кроме того, попробуйте запустить с помощью 'set -x', чтобы увидеть, действительно ли ваша команда действительно расширяет переменные так, как вы хотите - частое сохранение кода в переменных часто не работает так, как ожидают люди (см. Http://mywiki.wooledge.org/BashFAQ/050) –

+0

Кажется, вы передаете один аргумент вашему сценарию, заключенному в одинарные кавычки, что-то вроде './myscript 'Work/$ PLATFORM_SPECIES/test_reports/clock-reset/Ac_coherency06 -iname" Ac_coherency06 * .csv " «'. Это не сработает: после разделения слов (и, надеюсь, нет файлов, соответствующих вашему glob), 'find' увидит три аргумента' Work/$ PLATFORM_SPECIES/test_reports/clock-reset/Ac_coherency06', '-iname' и '' Ac_coherency06 * .csv "' с кавычками: указанный каталог (скорее всего) не существует, и даже если он существует, нет файлов, соответствующих из-за кавычек. –

+0

Ну, на самом деле вы, вероятно, передаете два аргумента как «./myscript» Work/$ PLATFORM_SPECIES/test_reports/clock-reset/Ac_coherenc y06 '' -iname "Ac_coherency06 * .csv" '(есть несоответствие с вашим скрипт и вывод, который вы нам даете), но в любом случае это неправильно. –

ответ

0

Если у вас есть команда, которая работает хорошо на корпусе, но не в вашем сценарии, то первое, что я хотел бы попробовать бы указать Bash по команде вызывается, увидеть, если это работает:

bash -c 'find Work/Linux4/test/test/test_goal/spyglass_reports/clock-reset/Ac_coherency06/ -iname "Ac_coherency*.csv"' 

Или еще лучше:

/bin/bash -c 'find Work/Linux4/test/test/test_goal/spyglass_reports/clock-reset/Ac_coherency06/ -iname "Ac_coherency*.csv"' 

Вы также можете сохранить результат на переменной или другую структуру данных, по мере необходимости, и передать его позже в сценарий, например:

ResultCommand="$(bash -c 'find Work/Linux4/test/test/test_goal/spyglass_reports/clock-reset/Ac_coherency06/ -iname "Ac_coherency*.csv"')" 

Edit: этот ответ был отредактирован более чем один раз, чтобы исправить возможные проблемы.

+0

Я бы не назвал этот звуковой совет в целом - особенно с использованием двойных кавычек, поскольку вы здесь, означает, что в других сценариях, где выполняется код, который включает в себя переменные разыменования, инкапсуляция таким образом добавляет сложности и место для ошибок способ правильно различать кавычки, расширенные во внешней оболочке, и те, которые были расширены во внутренней оболочке. –

+0

Чарльз, спасибо за ваши комментарии. Я сделал это с двойными кавычками, потому что OP использует их на своем посту. Использование двойных кавычек позволяет искать имена файлов, на которых есть пробел, например: 'Ac_coherency завтра * .csv', и они также позволяют OP использовать переменную в файле имен, например:' \ '$ something \ «'. Я подозреваю, что OP использовал двойные кавычки, потому что он мог бы использовать эти возможности в какой-то момент. Двойные кавычки добавляют некоторую сложность, но также добавляют некоторые возможности. –

+0

Вышеупомянутый комментарий на самом деле помогает сделать мой вывод: в примере '' ... \ "$ foo \" ... "' кавычки с экранированной обратной косой чертой являются только синтаксическими для * внутренней * оболочки (тот, который был запущен с 'bash -c'); для * внешней * оболочки, той, которая * выполняет * вашу команду 'bash -c', они не имеют никакого значения. Это двойное расширение может иметь существенные непредвиденные последствия: если ваш '$ foo' расширяется до' $ (rm -rf ~) ', когда внешняя оболочка запускает его, то внутренняя оболочка снова расширится; тогда как если внешняя оболочка не расширилась, а внутренняя оболочка расширила '$ foo', это было бы безопасно. –

0

Если вы позволяете список find предикатов будет принят, держать их в форме списка, один аргумент find на аргумент вашего сценария. В качестве примера реализован таким образом:

#!/bin/bash 

# read report_dir off the command line, and shift it from arguments 
report_dir=$1; shift 

# generate a version of report_dir for human consumption 
re='Work/.*/test_reports' 
replacement='Work/PLATFORM/test_reports' 
if [[ $report_dir =~ $re ]]; then 
    report_dir_name=${report_dir//${BASH_REMATCH[0]}/$replacement} 
else 
    report_dir_name=$report_dir 
fi 

# read results from find -- stored NUL-delimited -- into an array 
# using NUL-delimited inputs ensure that even unusual filenames work correctly 
declare -a list_of_csv 
while IFS= read -r -d '' filename; do 
list_of_csv+=("$filename") 
done < <(find "$report_dir" '(' "[email protected]" ')' -print0) 

# Use the length of that array to determine whether we found contents 
echo "Found ${#list_of_csv[@]} files" >&2 

if ((${#list_of_csv[@]} == 0)); then 
    echo "No files found in $report_dir_name" >&2 
fi 

Здесь shift потребляет первый аргумент из списка, и "[email protected]" относится ко всем остальным, которые остаются после этого момента. Это означает, что элементы, которые вы хотите передать отдельным отдельным аргументам в find, могут (и должны) передаваться как отдельные индивидуальные аргументы в ваш скрипт.

Таким образом, с использованием yourscript "/path/to/report/dir" -name '*.txt', на начальном этапе, $1 будет /path/to/report/dir, $2 будет -name и $3 будет *.txt. Однако после shift, $1 будет -name, а $2 будет *.txt; и "[email protected]" будут относиться к обоим из них, каждый из которых передается как отдельное слово.


  • Для получения дополнительной информации по использованию while read петли для чтения элементов прочь из потока, см BashFAQ #001.
  • Для получения дополнительной информации о синтаксисе, используемого для Баш-родной замены строки см BashFAQ #100 или http://wiki.bash-hackers.org/syntax/pe
  • Подробные сведения о массивах оболочки, в том числе ${#arrayname[@]}, чтобы проверить их длину или "${arrayname[@]}" расширить их содержание, см BashFAQ #005.

 Смежные вопросы

  • Нет связанных вопросов^_^