Ответы:
Если вы хотите переместить все, кроме каталогов, из $SOURCE_DIR
в $TARGET_DIR
, вы можете использовать эту команду:
find "$SOURCE_DIR" -maxdepth 1 -not -type d -exec mv -t "$TARGET_DIR" -- '{}' +
Подробно объяснил:
find
: Поиск поиск файлов в каталоге$SOURCE_DIR
: Каталог для поиска в-maxdepth 1
: Не заглядывать внутрь подкаталогов-not -type d
: Игнорировать каталоги
-type f
если вы хотите копировать только те файлы, которые являются строго файлами, но я предпочитаю вышеупомянутое, потому что оно также ловит все, что не является ни файлом, ни каталогом (в частности, символические ссылки)-exec mv -t "$TARGET_DIR" -- '{}' +
: Запустите команду, mv -t "$TARGET_DIR" -- FILES...
где FILES...
находятся все подходящие файлы (спасибо @DavidFoerster)Я думаю, что вы хотите записать только свои файлы. Сначала перейдите в ваш каталог и используйте эту команду, замените $ TARGET вашим целевым путем к каталогу. Если вы хотите скопировать ваши файлы, замените mv
на cp
.
find . -type f -exec mv {} $TARGET \;
если я объясню это, find . -type f
означает выбрать все файлы и -exec mv {} $TARGET \;
означает выполнить mv
команду для всех выбранных элементов.
Предыдущий ответ имеет ошибку .. mv
все файлы внутри подкаталогов также. Быстрое решение заключается в использовании -maxdepth 1
. Тогда это не рекурсивно mv
файлы в подкаталогах. Ниже правильный.
find . -maxdepth 1 -type f -exec mv {} $TARGET \;
-type f
Не мешает рекурсию.
При работе с файлами рекурсивно, find
это путь. В данном конкретном случае это не обязательно, но можно использовать с -maxdepth 1
другими, как показывают другие ответы.
Простая команда python может сделать это также. Вот пример:
$ tree
.
├── a_directory
└── a_file
$ python -c "import os,shutil;fl=[f for f in os.listdir('.') if os.path.isfile(f)];
> map(lambda x:shutil.move(x,'./a_directory'),fl)"
$ tree
.
└── a_directory
└── a_file
1 directory, 1 file
fl=[f for f in os.listdir('.') if os.path.isfile(f)]
перебирает все os.listdir('.')
найденные элементы, и мы проверяем, является ли элемент файлом, используя os.path.isfile()
функцию.
Как только fl
список файлов построен, мы используем map()
функцию. Эта функция принимает два аргумента - функцию и список элементов; он будет выполнять функцию, которую мы дали для каждого файла в списке. Таким образом, здесь мы имеем в lambda x:shutil.move(x,'./a_directory')
качестве анонимной функции, которая будет перемещать данный файл в заданный каталог, а затем у нас есть fl
список файлов, которые мы создали.
Для удобства чтения и общего использования мы также можем переписать его как общий скрипт на python, который принимает два аргумента - исходный каталог и целевой подкаталог.
#!/usr/bin/env python3
from os import listdir
from os.path import isfile,realpath
from os.path import join as joinpath
from shutil import move
from sys import argv
# this is script's full path
script=realpath(__file__)
# get all items in a given directory as list of full paths
fl=[ joinpath(argv[1],f) for f in listdir(argv[1]) ]
# filter out script itself ( just in case) and directories
fl_filtered = [ f for f in fl if isfile(f) and not script == realpath(f) ]
# Uncomment this in case you want to see the list of files to be moved
# print(fl_filtered)
# move the list of files to the given destination
for i in fl_filtered:
move(i,argv[2])
И использование так:
$ tree
.
├── a_directory
├── a_file
└── files2subdir.py
1 directory, 2 files
# Notice: the script produces no output unless you uncomment print statement
$ ./files2subdir.py "." "./a_directory"
$ tree
.
├── a_directory
│ └── a_file
└── files2subdir.py
Если вы используете zsh вместо bash, вы можете сделать это:
mv "$SOURCE"/*(.) "$TARGET"
(.)
В конце называется Глоб классификатор; .
внутри конкретно означает соответствовать только обычным файлам.
Делать это mv *(.) "$target"
быстро и практично. Однако, если вы делаете это как часть сценария, вы можете вместо этого написать что-то вроде того, что предложили Frxstrem и David Forester mv -t "$target" -- *(.)
, чтобы лучше обрабатывать угловые случаи, которые могут возникнуть при использовании другими людьми.
mv -t "$TARGET" -- "$SOURCE"/*(.)
было бы безопаснее (в случае, если он "$TARGET"
начинается с -
или не является каталогом). Мне действительно нравится решение Zsh!
Чтобы переместить все, кроме каталогов из source-dir
каталога в destination-dir
каталог, в Python:
#!/usr/bin/env python3
"""Usage: mv-files <source-dir> <destination-dir>"""
import shutil
import sys
from pathlib import Path
if len(sys.argv) != 3:
sys.exit(__doc__) # print usage & exit 1
src_dir, dest_dir = map(Path, sys.argv[1:])
for path in src_dir.iterdir():
if not path.is_dir():
shutil.move(str(path), str(dest_dir / path.name))
import mypackage
доfrom mypackage import ...
from __future__
импорт и обычный from pathlib
импорт.
import module
должно быть первым (импорт из библиотеки и сторонних производителей) from module import object
должно быть последним (локально / специфично для библиотеки)
Я бы использовал
mv *.*
это будет работать до тех пор, пока ваши папки не имеют расширений.
find ... -exec mv -t "$TARGET_DIR" -- '{}' +
будет более безопасным (если$TARGET_DIR
каталог отсутствует или начинается совпадение-
) и более эффективным (поскольку он не порождает новый подпроцесс для каждого сопоставленного файла).