Обычно плохая идея разбирать выходные данные ls
или find
, потому что нельзя различить, какие символы являются частью имени файла, а какие - разделителями. Если вы не контролируете имена файлов, это может быть дырой в безопасности, позволяющей противнику создавать имена файлов, которые приводят к выполнению сценарием произвольного кода. Смотрите Почему мой скрипт оболочки давится пробелами или другими специальными символами?. Однако, в вашем случае это может быть нормально, тем более, что ваши файлы выглядят как некое дерево исходного кода, где часто встречаются имена файлов без "экзотических" символов, в частности, без пробелов.
Тем не менее, на самом деле не сложнее использовать надежную команду. Основная идея заключается в том, чтобы заставить find
вызывать mv
вместо разбора вывода find
. Следующая команда рекурсивно перемещает .xml
из текущей директории и подкаталогов:
find . ! -type d -name '*.xml' ! -name deposit.xml -exec mv {} ./Archive \;
Чтобы немного ускорить процесс, можно сгруппировать вызовы mv
, запустив промежуточный оболочку.
find . ! -type d -name '*.xml' ! -name deposit.xml -exec sh -c 'mv "$@" "$0"' ./Archive {} +
Если вы собирались перемещать только файлы из текущей директории, без обхода подкаталогов, то вы должны инструктировать find
не рекурсивно:
find . ! -type d -name '*.xml' ! -name deposit.xml -exec mv {} ./Archive \;
для этого нужно сгруппировать вызовы mv
. Если ваша реализация find
поддерживает опцию -maxdepth
:
find . -maxdepth 1 ! -type d -name '*.xml' ! -name deposit.xml -exec sh -c 'mv "$@" "$0"' ./Archive {} +
Иначе:
find . -name . -o -type d -prune -o -name '*.xml' ! -name deposit.xml -exec sh -c 'mv "$@" "$0"' ./Archive {} +
Если ваша оболочка - это ksh, вы можете использовать ее расширенные глобусы. Это проще, чем использовать find
, но менее переносимо. Для перемещения файлов в текущем каталоге:
mv !(deposit).xml Archive/
В ksh93, для перемещения файлов из подкаталогов также:
set -o globstar
mv **/!(deposit).xml Archive/
В bash вы можете использовать шаблон !(...)
, но сначала вам нужно запустить shopt -s extglob
. Чтобы использовать шаблон **/
, вам нужно сначала запустить shopt -s globstar
и остерегаться, что до bash 4.2, **/
в дополнение к каталогам будет осуществляться переход по символическим ссылкам на каталоги.
shopt -s extglob globstar
mv **/!(deposit).xml Archive/
В zsh можно использовать шаблон !(...)
после выполнения setopt ksh_glob
. В качестве альтернативы можно использовать синтаксис zsh после выполнения setopt extended_glob
. Синтаксис рекурсивного обратного пути доступен в любом случае.
setopt extglob
mv **/(^deposit).xml Archive/
Хорошо, думаю, я понял.
Ваш Источник: (?
regex захватывает, в группе ,
все после
Источника:
до последнего /
на линии.
Таким образом, для вашего примера, он захватывает /диск/средства массовой информации/камеру/
.
Чтобы запечатлеть имя файла изображения JPEG, вам нужно
Source: .*/(?<group>.*)\n…
OK, ну вот опять.
Я полагаю, что вы / получаете нужную вам статическую обратную ссылку.
Проблема в том, что вы не получаете обратную ссылку.
которые, как ты думаешь, ты получаешь.
Я думаю, что ваша группа захвата (и последующая обратная ссылка) всего лишь /
.
Я не понимаю, почему это случилось,
за исключением того, чтобы сделать дикое предположение, что .*
работает в не жадном режиме,
поэтому .*/
перехватывает все через первый /
.
Может быть, ?
каким-то образом интерпретируется как означающее это.
Я полагаю, что то, что вы хотите, может быть
Source: (?<group>.*/)[^/]*\n…
, что заставляет .*/
захватить все через последнее /
.