Как копировать файлы в оболочке, которые не заканчиваются определенным расширением файла - PullRequest
0 голосов
/ 03 января 2011

Например, скопируйте все файлы, которые не заканчиваются на .txt

Ответы [ 7 ]

4 голосов
/ 03 января 2011

Bash примет не шаблон.

cp !(*.txt)
1 голос
/ 03 января 2011

Либо сделать:

for f in $(ls | grep -v "\.txt$")
do
  cp -- "$f" ⟨destination-directory⟩
done

или если у вас огромное количество файлов:

find -prune \! -name "*.txt" -exec cp -- "{}" ⟨destination-directory⟩ .. \;

Две вещи здесь, чтобы комментировать. Одним из них является использование двойного дефиса при вызове cp, и цитировании $f. Первые защищают от «дурацких» имен файлов, которые начинаются с дефиса и могут быть интерпретированы как опции. Второй охранник повторяет имена файлов с пробелами (или что в IFS).

1 голос
/ 03 января 2011

Вы можете положиться на:

find . -not -name "*.txt"

Используя:

find -x . -not -name "*.txt" -d 1 -exec cp '{}' toto/ \;`

, который копирует все файлы, которые не являются .txt текущего каталога, в подкаталог toto /.-d 1 используется для предотвращения рекурсии здесь.

1 голос
/ 03 января 2011

В зависимости от того, сколько предположений вы можете сделать относительно символов в именах файлов, это может быть так просто:

cp $(ls | grep -v '\.txt$') /some/other/place

Если это не сработает для вас, тогда, возможно, вместо этого можно будет использовать find ... -print0 | xargs -0 cp ... (хотя это имеет проблемы - потому что пункт назначения находится в конце списка аргументов).

В MacOS X xargs имеет опцию -J, которая поддерживает то, что необходимо:

-J replstr

Если указана эта опция, xargs будет использовать данные, считанные из стандартного ввода, чтобы заменить первое вхождение replstr вместо append- эти данные после всех других аргументов. Эта опция не влияет на количество аргументов, которые будут считаны из ввода (-n), или на размер Команда (ы) xargs будет генерировать (-s). Опция просто перемещается туда, где эти аргументы будут помещены в выполняемые команды. replstr должен отображаться в качестве отдельного аргумента для xargs. Он не будет распознан, если, например, он находится в середине строки в кавычках. Кроме того, будет заменено только первое вхождение replstr. Например, следующая команда скопирует список файлов и каталоги, которые начинаются с заглавной буквы в текущем каталоге до destdir:

/bin/ls -1d [A-Z]* | xargs -J % cp -rp % destdir

Похоже, что GNU xargs не имеет -J, но имеет связанную, но слегка ограничивающую опцию -I (которая также присутствует в MacOS X):

-I replace-str

Заменить вхождения replace-str в начальных аргументах на имена читаются из стандартного ввода. Кроме того, пробелы без кавычек не завершить ввод элементов; вместо этого разделитель является новой строкой персонаж. Подразумевает -x и -L 1.

1 голос
/ 03 января 2011

Вы можете использовать ls с опцией grep -v:

for i in `ls | grep -v ".txt"`
do
    cp $i $dest_dir
done
0 голосов
/ 03 января 2011

В zsh:

setopt extendedglob
cp *^.txt /some/folder

(если вы просто хотите файлов ) ...

cp *.^txt(.) /some/folder

Больше информации о zsh globbing здесь и здесь .

0 голосов
/ 03 января 2011

Я бы сделал это так, где destination - это каталог назначения:

ls | grep -v "\.txt$" | xargs cp -t destination

Edit: добавлено "-t" благодаря комментариям

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...