У меня такая ситуация, когда я хочу исключить каталог при использовании команды mv
. Я видел этот пример, где синтаксис был бы !(exclude_dir)
, но когда я настраивал сценарий для его тестирования, я получал результаты, которые я не до конца понимаю.
Теперь я создал три папки: f1
, f2
и f3
. Теперь я использую команду следующим образом:
mv -t f3/ !(f1) f2
Это приводит к этой ошибке:
mv: cannot move 'f3' to a subdirectory of itself, 'f3/f3'
mv: cannot stat 'f2': No such file or directory
Теперь забавно то, что структура папки теперь:
.
├── f1
└── f3
└── f2
3 directories, 0 files
Он делает то, что я хочу, но почему сообщения об ошибках. Очевидно, я не правильно использую эту команду.
Это не имеет никакого отношения mv
, но a bash
функция, цитируя man bash
:
Если опция оболочки extglob включена с помощью shopt встроенного, несколько расширенных операторов сопоставления с образцом распознаны. В следующем описании список шаблона является списком одного или нескольких шаблонов, разделенных |. Составные шаблоны могут быть сформированы с помощью одного или нескольких следующих подшаблонов:
! (список шаблона)
Соответствия что-либо кроме одного из данных шаблонов
!(f1)
соответствия f2 f3
в Вашем примере так эффективно Вы делаете:
mv -t f3/ f2 f3 f2
Для достижения цели, необходимо скорее сделать:
mv -t f3/ !(f[13]) # or !(f1|f3)
Это выражение соответствует всему кроме f1
и f3
.
Это также работает с *
, ?
и […]
:
$ ls
e1 e2 e3 f1 f2 f3
$ ls !(e*|?[12])
f3
!(f1)
является расширенным глобальным выражением , поэтому (при условии, что установлена опция оболочки extglob
) оно расширяется до списка (не) совпадающих файлов. Другими словами, если ваш каталог изначально содержал f1
, f2
, f3
, то
mv -t f3/ !(f1) f2
расширяется как
mv -t f3/ f2 f3 f2
Первая ошибка должна быть очевидной; вторая причина в том, что он пытается двинуться f2
дважды - и терпит неудачу во второй раз.
В качестве альтернативы вы также можете использовать rsync
:
rsync -arv --exclude = .ccache --exclude = build / home / ben / media / ben / thumbdrive /
Если вы ищете способ резервного копирования текущих файлов, было бы безопаснее разделить команду перемещения на копировать и удалить. Например:
# Allow wildcard and hidden files search
shopt -s extglob dotglob
# Make a new directory (skip if exists)
mkdir -p BACKUP
# Copy all files to BACKUP (-a to keep attributes, -f to overwrite existing)
cp -af !(BACKUP) BACKUP/
# Remove all files except BACKUP (and hidden files starting with ".keep")
rm -rf !(BACKUP|.keep*)