Как использовать find, чтобы скопировать все найденные файлы под новым именем в их же каталоги?
8239
Michael Prescott
У меня есть простая команда, которая делает почти то, что я хочу. Следующие файлы найдут все файлы с суффиксом «_compressed.swf» и скопируют каждый в один и тот же каталог с добавленным «.bak2»:
Результаты в: /content/somefile_compressed.swf Выход: /content/somefile_compressed.swf.bak2
Однако мне нужно заменить '_compressed.swf' на '_content.swf', который я хотел бы использовать вместо консистентности рекурсивного флага на cp.
Цель в: /content/somefile_compressed.swf Выход: /content/somefile_content.swf
Перекрестные сообщения здесь: http://serverfault.com/questions/115880/how-do-i-use-find-to-copy-all-found-files-to-a-new-name-in-their-same -directories
Dennis Williamson 14 лет назад
1
Есть также известный сценарий rename.pl, который распространяется вместе с Perl, и команда rename, которая могла бы сделать это немного проще. Они доступны не во всех дистрибутивах, но по большей части эти команды.
Вышеприведенное перемещает файлы из их текущего местоположения в местоположение скрипта и добавляет суффикс «content.swf». Замена mv на cp приближает меня, но мне все равно нужно заменить текст в имени, а не добавлять. Я становлюсь ближе, используя sed, но все еще учусь.
Michael Prescott 14 лет назад
0
@ Майкл, ты прав! возгласы. Я проводил тестирование только в текущем каталоге, поэтому и работал у меня. Я исправил это :)
John T 14 лет назад
0
Эй, спасибо Джон. Мне это нравится. Многое из этого все новое для меня. Я понимаю использование find, -exec, sh, dirname {}, basename {}, но меня немного смущает комбинированное использование. sh -c '' преобразует строку в команду и запускает команду, верно? mv {} расширяется до одного из результатов поиска "mv ../content/file1of20_compressed.swf ???????" Это вторая часть того, чего я пока не понимаю. Что вызывает замену сжатого.swf на content.swf? В моем решении вы можете видеть, что я только что узнал, как использовать sed.
Michael Prescott 14 лет назад
0
@ Майкл, что происходит, файл перемещается с новым именем. Если `{}` содержал `/ etc / somefile_compressed.swf`, dirname принимает` / etc`, а `basename {} compress.swf` оставит вас с` somefile_`. Теперь вы сложите эти 2 вместе с косой чертой, которую я добавил в середине (`/`), и у вас будет `/ etc / somefile_`. Вы заметите, что я добавил `content.swf` в конец, чтобы он завершил оператор как` / etc / somefile_content.swf`. НТН.
John T 14 лет назад
2
я бы использовал * rename.pl *, если бы требовалась функциональность * mv * (нетрудно добавить ее в любую систему с Perl), но * cp * делает это другим зверем. вам придется настроить скрипт, чтобы сделать копию вместо переименования, что будет работать, но это больше работы. @John - приятно * найти * решение; он большой, длинный и некрасивый, но, похоже, это сработает. (не проси меня помочь проверить это!) :)
quack quixote 14 лет назад
0
@ ~ шарлатан, я полностью пропустил часть cp! исправлено, спасибо :)
John T 14 лет назад
0
1
Michael Prescott
Я уверен, что все это может быть обработано в одну строку. Я очень близко подошел к решению в одну строку и с некоторой помощью еще ближе, но безуспешно. Следующие работы:
#!/bin/bash # Read all file names into an array FilesArray=($(find "../content" -name "*_compressed.swf")) # Get length of an array FilesIndex=${#FilesArray[@]} # Use for loop read all directory names for (( i=0; i<$; i++ )); do source="$" destination="$(echo "$" | sed 's/compressed/content/')" cp "$" "$" done exit 0;
0
jonathanserafini
Я считаю, что это должно сработать и может быть разложено на один вкладыш, если вам действительно это необходимо;)
find ../content -name '*_compressed.swf' | while read file do cp "$file" "$" done
Подстановка шаблонов Bash хорошо работает в этих случаях.