Список виключення командного рядка mv


11

Чи є спосіб mv, cpабо будь-яка операція файлу таким чином, що я міг би вказати всі файли , які я НЕ хочу впливають?

Наприклад, скажімо , у мене є папка з файлами file1, file2і file3, і я хочу , щоб рухатися file1і file2куди - то. Замість того, щоб явно називати файли для переміщення ( mv file1 file2 /path/to/destination), я хочу назвати файли, які не рухаються, і перенести всі інші в папці ( mv --some-switch file3 /path/to/destination)


Я вважаю, що mv file1 file2 /path/to/destinationце не зробить те, що ви хочете, щоб це зробити
phunehehe

Відповіді:


19
  • Ви можете використовувати розширені шаблони глобалізації в деяких оболонках, щоб відповідати всім файлам у каталозі, за винятком тих, що відповідають певному шаблону. Наприклад, команда в ksh, bash або zsh

    shopt -s extglob   ## needed in bash only
    setopt ksh_glob   ## needed in zsh only
    mv /source/!(*.bak) /destination
    

    перемістить усі файли /sourceдо, /destinationза винятком відповідності файлів *.bak. У zsh ви також можете записати, /source/^*.bakякщо ви запускаєте спочатку setopt extended_glob, і в більш загальному випадку (знову вимагається setopt extended_glob) /source/*~*.bak(або /source/a*~*.bakдля всіх файлів, ім’я яких починається за aвинятком .bakфайлів тощо).

  • Zsh має масову команду копіювання / переміщення / посилання, яку можна використовувати, серед інших, для переміщення всіх файлів, крім тих, що відповідають шаблону. Наприклад, наступна команда переміщує всі файли, крім *.bakвід /sourceдо target, і додає .bakдо їх імені в процесі:

    autoload zmv
    zmv '/source/(*)~*.bak' '/target/$1.bak'
    
  • Є кілька команд, які називаються renameплаваючими навколо. На Debian і Ubuntu /usr/bin/rename- це сценарій perl, який переміщує файли до нового імені, згенерованого виразом perl. Ви можете виключити файли з перейменування, не генеруючи нове ім'я, якщо файл потрібно виключити. Наприклад, наступна команда (за допомогою цієї конкретної renameпрограми) переміщує всі файли, крім *.bakвід : /sourceдо /target:

    rename 's!/source!/target! unless m!\.bak$!' /source/*
    
  • За допомогою findкоманди можна вибрати файли, які потрібно перемістити. Наприклад, наступна команда переміщує всі звичайні файли , за винятком того, *.bakв /sourceабо підкаталозі в /target(зверніть увагу , що структура каталогів зруйнувалася):

    find /source -type f \! -name '*.bak' -exec mv {} /target/ \;
    

    або (ефективніше, якщо потрібно перемістити багато файлів)

    find /source -type f \! -name '*.bak' -exec sh -c 'mv "$@" "$0"' /target/ {} +
    
  • rsyncце узагальнення cpта scpз дуже потужними правилами включення / виключення. Наприклад, наступна команда копіює всі файли , за винятком *.bakв /sourceабо підкаталог в /target, поважаючи структуру каталогів:

    rsync -a --exclude '*.bak' /source/ /target/
    
  • paxє (серед іншого) іншим cpна стероїди. Правила виключення не настільки потужні, як у rsync, але вони мають додаткову можливість перейменувати файли під час їх копіювання. Якщо ви перейменовуєте файл у порожній рядок, він виключається з копії. Наприклад, наступна команда копіює всі файли , за винятком *.bakв /sourceабо підкаталог в /targetі перейменовує файли .bakмимохідь.

    cd /source && pax -rw -pp -s '/.*\.bak$//' -s '/$/.bak/' . /target/
    

    Наведений вище приклад має невдалий побічний ефект створення каталогів під назвою foo.bak, яких можна уникнути, поєднуючи findз pax:

    { cd /source && find . -type f; } | \
    pax -rw -pp -s '/.*\.bak$//' -s '/$/.bak/' /target/
    

Дивовижно. Одне можливе виправлення: я думаю, що findкоманда повинна закінчитися\;
Стівен Д

@Steven: Дякую, я постійно забуваю, що ви можете використовувати лише +негайно наступні {}.
Жил "ТАК - перестань бути злим"

приємний список, THX для цього. :-)
ехокс

1
яка відповідь, великі пальці вгору :)
Dzung Nguyen
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.