Другие указали на проблемы с цитированием и выполнением.
Я предлагаю вам не использовать find -exec, а вместо этого найти список файлов и передать этот список в xargs и cp. Использование опции print0 поможет вам обойти любые «забавные» символы в именах файлов и каталогов
, например.
find sourcepath -name \*.mp3 -print0 \
| xargs -0 cp -t destinationpath
Преимущество этого заключается в том, что xargs будет собирать несколько имен файлов вместе из find и одновременно передавать их в cp, поэтому каждый экземпляр cp может копировать 20 или 100 файлов, а не запускать 1 вызов cp для каждого файла. xargs позаботится о том, чтобы вставить достаточное количество имен файлов в командную строку cp.
Вы также можете добавить параметр -P n к xargs, и он запустит несколько процессов cp параллельно.
На том основании, что ваши файлы находятся в той же файловой системе, что и целевая папка mp3. Вы можете добавить -l к cp, и он жестко свяжет файлы с местом назначения, а не копирует их.
напр.
find sourcepath -name \*.mp3 -print0 \
| xargs -0 -P 5 \
cp -l -t destinationpath
Поскольку вы отметили это с помощью vi и изначально спрашивали о vi, я объясню, почему это не работает в vi для вас , и как это исправить. Вы сказали, что изначально пытались:
%s/ab*/ab001/g
Метод *
работает в поиске, путем сопоставления предыдущего атома 0 или более раз, насколько это возможно. Из : h / *
:
*/star* */\star*
* (use \* when 'magic' is not set)
Matches 0 or more of the preceding atom, as many as possible.
В этом случае предыдущий атом - 'b', поэтому этот поиск будет соответствовать любому из этих:
a
ab
abbb
abbbbbbbbbbbbbbbbbbb
Он также будет соответствовать ab001
, но соответствует только его первой части, поэтому совпадение будет (ab) 001
. Vi видит, что вы искали это, и заменяет его на (ab001) 001
. Решение простое. Вы хотите сопоставить
'ab', за которым следует что-нибудь
. Точка (.
) будет соответствовать любому символу, кроме символа новой строки. Таким образом, если вы ищете
/ab.*/
, он будет соответствовать всему , начинающемуся с 'ab'. Итак, вы хотите:
:%s/ab.*/ab001/g
Если это слишком много совпадений (например, таких слов, как «абсолютно»), вы можете упростить это, чтобы искать только цифры. Например, это будет соответствовать 'ab', за которым следует любое количество цифр:
/ab\d*/
, и это будет соответствовать 'ab', за которым следуют ровно три цифры:
/ab\d\{3}/
Я бы рекомендовал добавить в закладки эту страницу для быстрого Ссылка на vi-regex. Я обнаружил, что это чрезвычайно ценно для устранения неполадок с некоторыми регулярными выражениями.
Вы пробовали
$ sed 's/ab\(.\+\)/ab001/g' -i file.txt
или
$ sed 's/\(^ab\).*/ab001/g' -i file.txt
Более простой и лучший способ, я думаю, надеюсь, это то, что вы ищете.
Вы можете сделать это с помощью awk
, как показано ниже:
cat input_file | awk '{if($1~/^ab/){print "ab001"}else{print $0}}'
Программа awk
будет искать, если первое поле вашего файла начинается с "ab", и заменит его на "ab001", используя символ ^
, который означает начало
выбранного вами поля, иначе выведите запись как есть.
Я бы попробовал perl oneliner
perl -i.bak -pe 's/\bab.*?\b/ab001/g;' [file(s)]
Регулярное выражение находит все элементы на границах слов, которые начинаются с 'ab' и заменяет их на 'ab001'
Я создал этот файл: ab001
ab002
ab003
ab004
ab005 ac001
ad0032 ab006
И этот скрипт perl выдал такой результат:
ab001
ab001
ab001
ab001
ab001 ac001
ad0032 ab001
что, как я думаю, вы и хотели.
Другие опции, которые я использовал, лучше всего объяснить в документации Perl по ссылке perlrun - как выполнить интерпретатор Perl