Моя поточна найкраща ставка:
for i in $(find . -name *.jpg); do echo $i; done
Проблема: не обробляє пробіли у назви файлів.
Примітка. Я також хотів би графічний спосіб зробити це, наприклад, команда "дерево".
Моя поточна найкраща ставка:
for i in $(find . -name *.jpg); do echo $i; done
Проблема: не обробляє пробіли у назви файлів.
Примітка. Я також хотів би графічний спосіб зробити це, наприклад, команда "дерево".
Відповіді:
Канонічний спосіб - це зробити
find . -name '*.jpg' -exec echo {} \;
(Замінити \;
з , +
щоб передати більше одного файлу echo
в той час)
або (специфічно для GNU, хоча деякі BSD також є):
find . -name '*.jpg' -print0 | xargs -r0 echo
zsh:
for i (**/*.jpg(D)) echo $i
echo
яке розширює схожі послідовності на зразок \b
(принаймні, відповідних Unix echo
).
find
відображається find . -type f -exec file '{}' \;
в EXAMPLES
розділі. Можливо, деякі снаряди будуть лікувати брекети спеціально.
'{}'
, \{\}
, {}
, "{}"
, '{'}
розкладаються оболонкою (незалежно від Борна типу оболонки) до одного аргументу , щоб знайти , що це два символи «{» і «}». Замініть "find" на "echo find", або printf '<%s>\n' find
якщо ви хочете двічі перевірити.
Кращі відповіді вже надані.
Але зауважте, що пробіли - не єдина проблема в наданому вами коді. символи вкладки, нового рядка та підстановки також є проблемою.
З
IFS='
'
set -f
for i in $(find . -name '*.jpg'); do echo "$i"; done
Тоді лише символи нового рядка є проблемою.
Те, що ви згадали, - одна з основних проблем, з якою стикаються люди, намагаючись прочитати імена файлів. Іноді люди з обмеженими знаннями та неправильним уявленням про структуру файлів і папок, як правило, забувають, що " У UNIX Все - це файл ". Тому вони не розуміють, що їм також потрібно обробляти пробіли, оскільки ім'я файлу може складатися з 2 або більше слів з пробілами.
Рішення. Отож, один з найбільш відомих способів зробити це чисте читання .
Ми тут прочитаємо всі наявні файли і збережемо їх у змінній, наступного разу, коли будете виконувати потрібну обробку, нам просто доведеться зберегти цю змінну всередині лапок, які збережуть імена файлів з пробілами. Це один з основних способів цього зробити, однак інші відповіді, надані іншими людьми тут, так само добре працюють.
СКРИПТ:
find /path/to/files/ -iname "*jpg" | \
while read I; do
cp -v --parent "$I" /backup/dir/
done
Тут я читаю файли, даючи шлях до них, і що я читаю, я зберігаю їх всередині змінної I, яку я цитую в подальшому під час обробки, щоб зберегти пробіли, щоб правильно обробити їх.
Сподіваюсь, це допоможе вам певним чином.
Просто з find
та bash
:
find . -name '*.jpg' -exec bash -c '
echo "treating file $1 in bash, from path : ${1%/*}"
' -- {} \;
Таким чином ми використовуємо $1
в bash, як і в базовому сценарії, що відкриває хороші перспективи для виконання будь-яких розширених (чи ні) завдань.
Більш ефективний спосіб (щоб уникнути необхідності запускати нову баш для кожного файлу):
find . -name '*.jpg' -exec bash -c 'for i do
echo "treating file $i in bash, from path : ${i%/*}"
done' -- {} +
В останній версії bash можна скористатися globstar
опцією:
shopt -s globstar
for file in **/*.jpg ; do
echo "$file"
done
Для простих дій ви можете навіть повністю пропустити цикл:
echo **/*.jpg
set -G
), він не повинен використовуватися в bash, оскільки версія bash принципово зламана (як і GNU grep -r
), оскільки вона спускається в посилання на каталоги (еквівалентні find -L
або zsh ***/*.jpg
). Також зауважте, що всупереч знаходженню він опустить dotfiles і не спуститься в dotdirs (за замовчуванням).
$i
? Я це роблю, і це прекрасно працює. Чи щось не так у цьому підході?