Прокрутите все файлы с определенным расширением
for i in $(ls);do
if [ $i = '*.java' ];then
echo "I do something with the file $i"
fi
done
Я хочу прокрутить каждый файл в текущей папке и проверить, соответствует ли он определенному расширению. Код выше не работает, знаете ли вы, почему?
Ответы
Ответ 1
Никаких причудливых трюков:
for i in *.java; do
[ -f "$i" ] || break
...
done
Защитник гарантирует, что, если нет соответствующих файлов, цикл завершится, не пытаясь обработать несуществующее имя файла *.java
. В bash
(или оболочки, поддерживающие что-то подобное), вы можете использовать опцию nullglob
просто игнорировать несоответствующее совпадение и не вводить тело цикла.
shopt -s nullglob
for i in *.java; do
...
done
Ответ 2
правильный ответ: @chepner
EXT=java
for i in *.${EXT}; do
...
done
однако, здесь небольшой трюк, чтобы проверить, имеет ли имя файла заданные расширения:
EXT=java
for i in *; do
if [ "${i}" != "${i%.${EXT}}" ];then
echo "I do something with the file $i"
fi
done
Ответ 3
Рекурсивно добавить подпапки,
for i in `find . -name "*.java" -type f`; do
echo $i
done
Ответ 4
как @chepner говорит в своем комментарии, вы сравниваете $i с фиксированной строкой.
Чтобы развернуть и исправить ситуацию, вы должны использовать [[]] с оператором regex = ~
например:
for i in $(ls);do
if [[ $i =~ .*\.java$ ]];then
echo "I want to do something with the file $i"
fi
done
регулярное выражение справа от = ~ проверяется на значение левого оператора и не должно быть процитировано (цитируется не будет ошибка, а будет сравниваться с фиксированной строкой и, скорее всего, сбой "
но @chepner ответ выше, используя glob - гораздо более эффективный механизм.
Ответ 5
Я согласен с другими ответами, касающимися правильного способа прокрутки файлов. Однако ОП спросил:
Код выше не работает, знаете ли вы, почему?
Да!
Отличная статья В чем разница между тестом, [и [[?] подробно объясняет, что среди других различий вы не можете использовать expression matching
или pattern matching
в команде test
(которая является сокращением для [
)
Feature new test [[ old test [ Example
Pattern matching = (or ==) (not available) [[ $name = a* ]] || echo "name does not start with an 'a': $name"
Regular Expression =~ (not available) [[ $(date) =~ ^Fri\ ...\ 13 ]] && echo "It Friday the 13th!"
matching
Так вот почему ваш script терпит неудачу. Если OP заинтересован в ответе с синтаксисом [[
(который имеет тот недостаток, что не поддерживается на столько платформ, как команда [
), я был бы счастлив отредактировать мой ответ, чтобы включить его.
РЕДАКТИРОВАТЬ: любые предупреждения о том, как форматировать данные в ответе в виде таблицы, были бы полезны!