Скопируйте все имена подкаталога и файлы с конкретным расширением нового каталога

У меня есть следующая структура каталогов:

dir1
    py1.py
    py2.py
    subdir1
        file1.py
        anotherfile.txt
    subdir2
        file2.py
        animage.png

Я хотел бы скопировать структуру папок и *.py файлы (кроме тех, которые принадлежат непосредственно dir1) к новому каталогу на том же уровне как dir1. Таким образом, я ищу это:

dir2
    subdir1
        file1.py
    subdir2
        file2.py

Я попробовал (от слоя выше dir1):

mkdir dir2
cp -r *.py ../dir2

Но это только скопировало *.py файлы с dir 1 в dir2 и проигнорировало подкаталоги.

4
задан 31 March 2020 в 00:55

4 ответа

Вы могли использовать шарик оболочки, с --parents опция cp

Напр. данный

$ tree dir1 dir2
dir1
├── py1.py
├── py2.py
├── subdir1
│  ├── anotherfile.txt
│  └── file1.py
└── subdir2
    ├── animage.png
    └── file2.py
dir2

2 directories, 6 files

(отметьте это dir2 уже существует), затем

$ cd dir1
$ cp --parents -t ../dir2 **/*.py
$ cd ..

дает

$ tree dir1 dir2
dir1
├── py1.py
├── py2.py
├── subdir1
│  ├── anotherfile.txt
│  └── file1.py
└── subdir2
    ├── animage.png
    └── file2.py
dir2
├── subdir1
│  └── file1.py
└── subdir2
    └── file2.py

4 directories, 8 files

Я использовал globstar шаблон ** но если только необходимо убывать один уровень, Вы могли бы использовать основное * подстановочный знак для подкаталогов.

2
ответ дан 7 April 2020 в 23:23

Можно сделать это с find и cpio, просто cd в dir1 и выполненный это:

find . -mindepth 2 -type f -name "*.py" -print | cpio -pdm ../dir2
  • find . запустится в текущем каталоге т.е. dir1
  • -mindepth 2 проигнорирует содержание текущего каталога т.е. dir1 и включайте содержание его подкаталогов.
  • -type f -name "*.py" -print будет включать только файлы с .py расширение.
  • cpio -pdm скопирует. -p создает список файлов, -d создает каталоги по мере необходимости и -m устанавливает корректное время изменения на каталогах.

  • ../dir2 создаст каталог (если он не будет существовать), названный dir2 каждый выравнивает рядом с dir1 и скопируйте все в него.

Поскольку ссылочный человек находит и человек cpio.

Всего наилучшего

1
ответ дан 7 April 2020 в 23:23

Хорошо, я не мог найти способ сделать CP, или rsync собой делают то, что Вы хотите, таким образом, я придумал:

for n in dir1/* ; do ls ${n}/*.py >/dev/null 2>&1 ; if [[ $? == 0 ]]; then mkdir dir2/${n/dir1\//} ; cp ${n}/*.py dir2/${n/dir1\//} ; fi ; done

Расположение с отступом его правильно делает его более читаемым:

for n in dir1/* 
do
  ls ${n}/*.py >/dev/null 2>&1 
  if [[ $? == 0 ]]
  then
    mkdir dir2/${n/dir1\//} 
    cp ${n}/*.py dir2/${n/dir1\//} 
  fi
done

Так, что я делаю, просматривает dir1, предполагая, что каждый файл является каталогом и пытающийся перечислить любые *.py файлы (с выводом и ошибкой, исчезающей в/dev/null). Очевидно, пробуя это за py1.py и py2.py перестанет работать, потому что они не каталоги. Это должно также перестать работать для любых каталогов, которые не имеют никаких *.py файлов в них.

Это означает это, когда мы находимся в если, результат предыдущей команды ($?) должно быть что-то другое, чем 0, и мы ничего не делаем. Для subdirs в dir1 список должен успешно выполниться, и таким образом, $? будет 0, таким образом, мы выполняем бит в цикле. Это просто создает subdir в dir2 (не забывающий ничем заменять "dir1 /") и копирует любые *.py файлы через.

Это - конечно, не единственный способ сделать это, и в то время как это работает на пример, Вы дали, это не работает, если у Вас есть дополнительные уровни subdirs внутри subdirs. (например. dir1/subdir1/subsubdir1/*.py не будет скопирован через),

0
ответ дан 7 April 2020 в 23:23

Использовать rsync:

mkdir dir2
rsync -amv --include '*/' --include '*/*.py' --exclude '*' dir1/ dir2

Это скопирует все .py файлы, начинающие со второго уровня.

  • -m постарайтесь не создавать пустые каталоги.
  • --include '*/' Включайте все каталоги
  • --include '*/*.py' Включайте все .py файлы, запускающиеся на втором уровне
    • Изменение в '/*/*.py' если Вы хотите включать только второй уровень .py файлы
  • --exclude '*' Исключите все, что не включено.
0
ответ дан 7 April 2020 в 23:23

Другие вопросы по тегам:

Похожие вопросы: