Используйте «find» вместо «for - do - done» для поиска в подкаталогах.
337
X-File
В OS X 10.8 у меня есть пара папок с изображениями, но не все файлы имеют правильное расширение, есть GIF-файлы с именем JPG и т. Д.
У меня есть одна строка, которая делает работу для фактического каталога:
for f in * ; do type=$(file "$f" | tr "[A-Z]" "[a-z]" | awk '') ; mv "$f" "$.$type" ; done
Теперь я хотел бы использовать «поиск» вместо того, чтобы также искать подпапки, но я всегда терплю неудачу.
Есть намеки?
Я должен быть более ясным: проблема не в «самом поиске», а в правильном именовании в конце, когда мне нужно использовать «{}» из команды поиска вместо «$ f» из цикла for. Извините за то, что не отвечал точно на мой вопрос.
X-File 7 лет назад
0
Примечание для следующего раза: Вы должны были опубликовать эти комментарии под ответом Бруно. Если они ниже вашего вопроса, никто не получит уведомление о них.
slhck 7 лет назад
0
В этом случае вы можете легко найти файлы, НЕ соответствующие расширению .jpg:
find . -type f -not "*.jpg"
Вы также можете просмотреть результаты и проверить, являются ли файлы на самом деле jpg:
find . -type f -not "*.jpg" | while read fname; do if [[ $(file $fname) == *"JPG"*]] then echo $fname fi done
Вы хотите использовать `find… -print0 | тогда как IFS = read -r -d '' fname`, см. также http://mywiki.wooledge.org/ParsingLs
slhck 7 лет назад
0
Tnx Bruno, `while read` - отличный способ решить эту проблему таким же образом, как и` for do done 'работа. И если бы мой вопрос был задан только для того, чтобы найти прагматичное решение, я с вами ;-) Но я действительно хочу знать, как это можно было бы проанализировать с помощью `find`.
X-File 7 лет назад
0
Я анализирую с `find` и перебираю результаты с чем-то другим (` while`, `for`, что угодно). В вашем решении вы вызываете find для каждого имени файла, возвращаемого `ls`. Может быть, вы имели в виду использование -exec?
Bruno9779 7 лет назад
0
0
slhck
Проще всего было бы включить рекурсивное сглаживание для файлов, например, в Bash:
shopt -s globstar for f in **/*.*; do type=$(file "$f" | tr "[A-Z]" "[a-z]" | awk '') mv -- "$f" "$.$type" done
Таким образом, вам не придется анализировать findвывод. Проблема в том, что если файлов слишком много, эта команда может завершиться ошибкой, поскольку она может превысить максимальный размер командной строки. Это связано с тем, что имена файлов в **/*.*Bash будут расширены до выполнения команды.
Таким образом, альтернатива заключается в использовании find, передавая свой вывод в whileи read.
find . -type f -print0 | while IFS= read -r -d '' f type=$(file "$f" | tr "[A-Z]" "[a-z]" | awk '') mv -- "$f" "$.$type" done