Список исключений из командной строки

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: Спасибо, я постоянно забываю, что вы можете использовать только +сразу после {}.
Жиль "ТАК - перестать быть злым"
хороший список, спасибо за это. :-)
echox
1
какой ответ, большие пальцы вверх :)
Дзунг Нгуен