Заменить слово на основе первых n символов

Другие указали на проблемы с цитированием и выполнением.

Я предлагаю вам не использовать 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
0
23.11.2016, 23:22
4 ответа

Поскольку вы отметили это с помощью и изначально спрашивали о 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. Я обнаружил, что это чрезвычайно ценно для устранения неполадок с некоторыми регулярными выражениями.

3
28.01.2020, 02:26

Вы пробовали

$ sed 's/ab\(.\+\)/ab001/g' -i file.txt

или

$ sed 's/\(^ab\).*/ab001/g' -i file.txt

Более простой и лучший способ, я думаю, надеюсь, это то, что вы ищете.

0
28.01.2020, 02:26

Вы можете сделать это с помощью awk, как показано ниже:

cat input_file | awk '{if($1~/^ab/){print "ab001"}else{print $0}}'

Программа awk будет искать, если первое поле вашего файла начинается с "ab", и заменит его на "ab001", используя символ ^, который означает начало выбранного вами поля, иначе выведите запись как есть.

0
28.01.2020, 02:26

Я бы попробовал 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

0
28.01.2020, 02:26

Теги

Похожие вопросы