
Я хочу скопировать все файлы и подкаталоги, за исключением файла данных с именем *.data, в целевой каталог.
[ichen@ui01 sub_test]$ ls
a.cxx a.data subdir
[ichen@ui01 sub_test]$ ls subdir/
sub_a.cxx sub_a.data
Вы можете видеть, что есть 2 файла данных во внешнем каталоге и подкаталоге соответственно. Я использовал эту команду:
[ichen@ui01 sub_test]$ cp -r !(*.data) ../destination_dir/
намеревался скопировать все файлы, кроме *.data, в место назначения, но это не работает в подкаталоге:
[ichen@ui01 destination_dir]$ ls
a.cxx subdir
[ichen@ui01 destination_dir]$ ls subdir/
sub_a.cxx sub_a.data
Выше вы можете видеть, что эта команда работает только в первом каталоге. Как сделать так, чтобы она работала во всех подкаталогах?
решение1
Вы не указали в своем вопросе, является ли это требованием сохранения структуры каталогов в копии или вам просто нужна копия файлов. Чтобы просто скопировать все файлы, не названные *.data, вы можете использовать это:
find . -type f ! -name '*.data' | xargs cp -t ../destination_dir/
С другой стороны, если вы хотите сохранить структуру каталогов, вы можете использовать что-то вроде этого:
for file in `find . ! -name '*.txt' | sed 's/^.\///'`; do if [ -d "./$file" ]; then mkdir -p "../destination_dir/$file"; else cp "./$file" "../destination_dir/$file"; fi; done
Не уверен, есть ли более простой способ сделать это, но эта команда делает следующее:
Найти все файлы и папки в текущем каталоге или его подпапках, не соответствующие *.data, затем для каждого:
Проверяет, является ли файл каталогом, и если это так, создает соответствующий каталог в каталоге назначения, или, если это файл, копирует его в место назначения.
Редактировать: Добавление версии скрипта оболочки:
#!/bin/bash
# Disable shell glob expansion within the script
# Required to stop bash from expndinging the glob in $1
set -f
for file in `find . ! -name $1 | sed 's/^.\///'`
do if [ -d "./$file" ]; then
mkdir -p "$2/$file"
else
cp "./$file" "$2/$file"
fi
done