копирование файлов с определенными именами в другую папку

копирование файлов с определенными именами в другую папку

У меня есть папка с большим количеством файлов. Я хочу скопировать все файлы, которые начинаются с этих имен (разделенных пробелом):

abc abd aer ab-x ate

в другую папку. Как это сделать?

решение1

С csh, tcsh, ksh93, bash, fishили zsh -o cshnullglob, вы можете использоватьрасширение скобкииподстановкачтобы сделать это ( --для этих имен файлов это не требуется, но я предполагаю, что это просто примеры):

cp -- {abc,abd,aer,ab-x,ate}* dest/

Если вы не хотите использовать раскрытие фигурных скобок, можно использовать цикл for (здесь синтаксис в стиле POSIX/Bourne):

for include in abc abd aer ab-x ate; do
    cp -- "$include"* dest/
done

Если у вас очень большое количество файлов, это может быть медленно из-за вызова cpодин раз на включение. Другой способ сделать это — заполнить массив и идти оттуда (здесь ksh93или zshнедавний bashсинтаксис):

files=()
includes=(abc abd aer ab-x ate)

for include in "${includes[@]}"; do
    files+=( "$include"* )
done

cp -- "${files[@]}" dest/        

решение2

Примечание о расширении скобок и подстановке.

Расширение скобок не является подстановкой (хотя в csh/tcsh, где оно возникло, это различие не столь очевидно, как в других оболочках). Оно выполняетсядоподстановка.

Итак, когда вы это сделаете:

cp {a,b}* /dest

Сначала он расширяется до:

cp a* b* /dest

Это означает, что оболочке придется развернуть два глобуса, то есть дважды получить полный список файлов и дважды посмотреть, какие из них соответствуют шаблону.

При использовании zsh, это также означает, что если какой-либо глобальный массив не соответствует ни одному файлу, вся команда отменяется (эту проблему можно обойти, включив опцию, cshnullglobведущую себя как в csh).

Это также означает, что если у вас есть

cp {a,ab}* /dest

cpскопирует ab*файлы дважды.

Это отличается от:

cp @(a|b)* /dest

или kshили bash -O extglob, zsh -o kshglobили

cp (a|b)* /dest

из zsh. Там, это толькоодинglob, поэтому это будет более эффективно, и файлы будут включены только один раз.

С помощью zsh, если у вас есть список префиксов в массиве:

prefixes=(abc abd aer ab-x ate)
cp -- (${(j:|:)~prefixes})* /dest

(выше префиксы рассматриваются как глоб). То есть объединяем элементы массивов |и рассматриваем результат как глоб ( ~).

Если список большой, вы можете обнаружить, что выполнение cpзавершается ошибкой"список аргументов слишком длинный"ошибка. В этом случае вы можете использовать zshвстроенную версию, cpкоторую вы можете загрузить, загрузив zsh/filesмодуль ( zmodload zsh/files).

решение3

  1. Например, у меня в текущем каталоге есть следующие файлы:

    1-s2.0-S0038092X0000058X-main.pdf  ANNDHW.pdf     HPcalculation2
    1-s2.0-S0306261999000422-main.pdf  ANNlee.pdf     HPcalculation3
    ANNCanada.pdf                      HPcalculation  HPcalculation4
    
  2. Я хочу переместить все файлы, начиная с HP, в папку:./NewFolder/

  3. Я могу сделать:

    cp ./HP* ./NewFolder/
    

    ./HP*скажет linux, что меня интересуют все файлы, начинающиеся с HP. Обратное — когда меня интересуют все файлы, заканчивающиеся на .pdf. Я могу поставить *перед .pdf:

    cp ./*.pdf ./NewFolder/
    

решение4

Просто вы можете сделать

 cp abc* abd* aer* ab-x* ate*  DestinationPath

Решение вашей расширенной проблемы может быть

  1. поместить все имена файлов в список, например list0.txt
  2. Копировать все с

    cp `cat list0.txt` DestinationPath # Не нужно пробелов в именах файлов

    или лучше,

    while read -r file; do cp "$file" dest/ ; done < list0.txt

Примечания:

  • "$file", потому что так вы можете обрабатывать имя с пробелами внутри, какOne Package.deb
  • -rэто защитит вас от побегов.

    -r Обратная косая черта не действует как экранирующий символ. Обратная косая черта считается частью строки. В частности, пара обратная косая черта-новая строка не может использоваться как продолжение строки

Связанный контент