Учитывая script ниже, я хотел бы избежать выполнения конвейера, если файл не существует.
Как я могу выйти из script сразу, если файл txt не найден?
ls */*.txt | grep ab1 | awk '{print $1, $1}' | sed "s/\"/\"\"/g" | xargs -L1 mv
Учитывая script ниже, я хотел бы избежать выполнения конвейера, если файл не существует.
Как я могу выйти из script сразу, если файл txt не найден?
ls */*.txt | grep ab1 | awk '{print $1, $1}' | sed "s/\"/\"\"/g" | xargs -L1 mv
Вы можете проверить наличие файла с чем-то вроде:
if [[ -f x.txt ]] ; then
echo file exists.
fi
Чтобы выйти, если этого не произойдет, достаточно:
if [[ ! -f x.txt ]] ; then
echo 'File "x.txt" is not there, aborting.'
exit
fi
-f <file>
- это только одно из многих условных выражений, которые вы можете использовать. Если вы посмотрите на bash
man-страницу в разделе CONDITIONAL EXPRESSIONS
, вы увидите весь их массив.
Если (как указано в обновлении вопроса) вы хотите проверить, приводит ли подстановочный знак к файлам, вы можете просто расширить его, отбросив ошибки. Если их нет, вы получите пустую строку, которая может быть обнаружена с помощью -z
:
if [[ -z "$(ls -1 */*.txt 2>/dev/null | grep ab1)" ]] ; then
echo 'There are no "*/*.txt" files.'
exit
fi
Обратите внимание, что я использовал -1
для принудительного создания одного файла на строку, хотя Linux ls
делает это по умолчанию, если устройство вывода не является терминалом (из памяти). Это на всякий случай, если вы попробуете это на машине, которая в этом случае не будет заставлять одну строку.
Имейте в виду, что если у вас есть пробелы в именах файлов, использование ls
и затем awk
для извлечения столбца 1 не будет работать слишком хорошо. Например, файл abc ab1.txt
приведет к извлечению только бит abc
.
Использование find
с -print0
, в сочетании с xargs
с -0
является обычным способом правильной обработки файлов, которые могут иметь в них "специальные" символы. Существует много других опций, которые вы можете предоставить find
для обеспечения обработки только необходимых файлов, таких как -maxdepth
, чтобы ограничить скорость перемещения по дереву каталогов и -name
, чтобы правильно фильтровать имена файлов.
Однако, если вы знаете, что у вас никогда не будет таких типов файлов, вероятно, хорошо использовать решение ls
, просто убедитесь, что вам комфортно с его недостатками.
test
Быстрый и короткий способ тестирования на существование:
test -e $FILENAME || exit
Вы можете связать его, выполнив:
test -e $FILENAME && something | something-else
В этом случае something
и something-else
будут выполняться только в том случае, если файл существует.
Например:
➤ test -e ~/.bashrc && echo True || echo False
True
➤ test -e ./exists-not && echo True || echo False
False
Кроме того: Обратите внимание, что [
является псевдонимом для test
. Семантика [[
определяется bash и может быть найдена в bash manpage
... вам, вероятно, лучше использовать find
для получения ваших файлов:
find ./ -maxdepth 2 -name "*ab1*.txt" -exec do-something-to-filename '{}' \;
Поскольку вывод ls
не может быть надежно проанализирован. Это также будет выполнять только команду do-something-to-filename
, если имя файла существует, что, как я думаю, вы пытаетесь сделать.
{}
будет заменен именем файла для каждого вызова do-something-to-filename
.
find ... -exec ...
или find ... -print0 | xargs -0 ...
, как правило, отлично, но вы можете сделать это напрямую с помощью glob с помощью опции bash nullglob
:
bash-3.2$ echo *foo
*foo
bash-3.2$ shopt -s nullglob
bash-3.2$ echo *foo
bash-3.2$
В зависимости от остальной части вашего script, вы можете или не захотите повторно установить его с помощью shopt -u nullglob
.
Я пробовал это, и это сработало для меня
test -s <<your file path>> && exit 0 || <<things to do when file NOT exists>>
Обратите внимание, что я действительно выхожу, когда файл отсутствует