for i in $(ls);do
if [ $i = '*.java' ];then
echo "I do something with the file $i"
fi
done
Я хочу перебрать каждый файл в текущей папке и проверить, соответствует ли он определенному расширению. Приведенный выше код не работает, знаете почему?
for i in $(ls *.java); do echo "do something with file $i"; done
?$i
буквальную строку "* .java"; Раскрытие паттернов здесь не выполняется.if [[ $i == *.java ]]; then
.. (обратите внимание на двойные [[]] s и * .java без кавычек).ls
разбирайте - примите ответОтветы:
Никаких хитрых уловок:
Защитник гарантирует, что при отсутствии подходящих файлов цикл завершится без попытки обработать несуществующее имя файла
*.java
. Вbash
(или в оболочках, поддерживающих нечто подобное) вы можете использоватьnullglob
опцию, чтобы просто игнорировать неудачное совпадение и не вводить тело цикла.источник
for i in *.java *.cpp; do
. Если вы расширили шаблоны включены вbash
сshopt -s extglob
, вы можете написатьfor i in *.@(java|cpp); do
.shopt -s nullglob
так, чтобы несоответствующий шаблон расширялся до пустой последовательности, а не обрабатывался буквально.cd
перейти в этот каталог, прежде чем начинатьfor
циклnullglob
ее обработку как пустую последовательность или настроитьfailglob
ее обработку как ошибку. (Если вы установите оба,failglob
имеет приоритет.)правильный ответ @ chepner's
однако вот небольшой трюк, чтобы проверить, имеет ли имя файла заданные расширения:
источник
ext
вместо.java
?Рекурсивно добавлять вложенные папки,
источник
find . -name "*.java" -type f -exec echo \{\} \;
чтобы избежать неправильного анализа выводаfind
"$i"
внутри цикла.Перебор всех файлов , заканчивающихся:
.img
,.bin
,.txt
суффикс, и напечатать имя файла:Или рекурсивным способом (также можно найти во всех подкаталогах):
источник
Я согласен с другими ответами относительно правильного способа просмотра файлов. Однако OP спросил:
Да!
Отличная статья В чем разница между test, [и [[?]] Подробно объясняется, что среди других различий вы не можете использовать
expression matching
илиpattern matching
внутриtest
команды (что является сокращением для[
)Вот почему ваш скрипт не работает. Если OP заинтересован в ответе с
[[
синтаксисом (недостаток которого заключается в том, что он не поддерживается на таком количестве платформ, как[
команда), я был бы счастлив отредактировать свой ответ, включив его.РЕДАКТИРОВАТЬ: Любые советы о том, как отформатировать данные в ответе в виде таблицы, были бы полезны!
источник
как @chepner говорит в своем комментарии, вы сравниваете $ i с фиксированной строкой.
Чтобы расширить и исправить ситуацию, вы должны использовать [[]] с оператором регулярного выражения = ~
например:
регулярное выражение справа от = ~ проверяется на соответствие значению левого оператора и не должно заключаться в кавычки (кавычки не будут ошибкой, но будут сравниваться с фиксированной строкой и, скорее всего, не удастся "
но ответ @chepner выше с использованием glob - гораздо более эффективный механизм.
источник
ext
вместо.java
?if [[ $i == *.java ]]
илиif [[ $i == *.$ext ]]
. Но неЯ нашел это решение весьма удобным. Он использует эту
-or
опцию вfind
:find . -name \*.tex -or -name "*.png" -or -name "*.pdf"
Он будет искать файлы с расширением
tex
,png
иpdf
.источник