Подтвердить что ты не робот

Прокрутите все файлы с определенным расширением

for i in $(ls);do
    if [ $i = '*.java' ];then
        echo "I do something with the file $i"
    fi
done

Я хочу прокрутить каждый файл в текущей папке и проверить, соответствует ли он определенному расширению. Код выше не работает, знаете ли вы, почему?

4b9b3361

Ответ 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 заинтересован в ответе с синтаксисом [[ (который имеет тот недостаток, что не поддерживается на столько платформ, как команда [), я был бы счастлив отредактировать мой ответ, чтобы включить его.

РЕДАКТИРОВАТЬ: любые предупреждения о том, как форматировать данные в ответе в виде таблицы, были бы полезны!