Как сделать что-то для каждого файла в каталоге с помощью bash?

Я начал с этого:

command *

Но это не работает, когда каталог пуст; * подстановочный знак становится буквенным символом "*". Поэтому я переключился на это:

for i in *; do
   ...
done

который работает, но опять же, если каталог пуст. Я прибегал к использованию ls:

for i in `ls -A`

но, конечно, тогда имена файлов с пробелами в них становятся разделенными. Я попытался использовать ключ -Q:

for i in `ls -AQ`

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

Ответы

Ответ 1

Предполагая, что вы хотите что-то делать только с файлами, простым решением является проверка, является ли файл $i файлом:

for i in * 
do
    if test -f "$i" 
    then
       echo "Doing somthing to $i"
    fi
done

Вы всегда должны делать такие тесты, потому что вы почти наверняка не хотите рассматривать файлы и каталоги одинаково. Обратите внимание на цитаты вокруг "$ i", которые предотвращают проблемы с именами файлов, содержащими пробелы.

Ответ 2

find может быть тем, что вы хотите.

find . | while read file; do
    # do something with $file
done

Или может быть так:

find . -exec <command> {} \;

Если вы не хотите, чтобы поиск включал подкаталоги, вам может потребоваться добавить команду -type f и -maxdepth 1 в команду find. Подробнее см. найти справочную страницу.

Ответ 3

Это зависит от того, собираетесь ли вы вводить это в командной строке и какую команду вы применяете к файлам.

Если он набирается, вы можете пойти со своим вторым выбором и заменить что-то безвредное для команды. Например, мне нравится использовать echo вместо mv или rm.

Поместите все это на одну строку:

for i in * ; do command $i; done

Когда это работает - или вы можете увидеть, где он терпит неудачу, и независимо от того, безопасно ли это, вы можете нажать стрелку вверх, отредактировать команду и повторить попытку.

Ответ 4

Использовать shopt для предотвращения расширения *.txt

shopt -s nullglob
for myfile in *.txt
do
    # your code here
    echo $myfile

done

Ответ 5

это должно сделать трюк:

find -type d -print0 | xargs -n 1 -0 echo "your folder: {} !"
find -type f -print0 | xargs -n 1 -0 echo "your file: {} !"

print0/0 есть, чтобы избежать проблем с пробелами