Как переместить только файлы из текущей папки в подпапку?

9

Мне не нужно перемещать папки, только файлы.

Я пробовал, mv *но эта команда также перемещает папки.

Archit
источник

Ответы:

13

Если вы хотите переместить все, кроме каталогов, из $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)
Frxstrem
источник
2
find ... -exec mv -t "$TARGET_DIR" -- '{}' +будет более безопасным (если $TARGET_DIRкаталог отсутствует или начинается совпадение -) и более эффективным (поскольку он не порождает новый подпроцесс для каждого сопоставленного файла).
Дэвид Фёрстер
@DavidFoerster Спасибо, обновлено (тоже узнал что-то новое сегодня!)
Frxstrem
5

Я думаю, что вы хотите записать только свои файлы. Сначала перейдите в ваш каталог и используйте эту команду, замените $ 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Не мешает рекурсию.
Мартин Торнтон
@MartinThornton спасибо за ваше предложение .. я отредактирую свой ответ ...
Эмальша Расад
3

Python подход

При работе с файлами рекурсивно, 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
Сергей Колодяжный
источник
Вот другой подход Python
JFS
3

Если вы используете zsh вместо bash, вы можете сделать это:

mv "$SOURCE"/*(.) "$TARGET"

(.)В конце называется Глоб классификатор; .внутри конкретно означает соответствовать только обычным файлам.

Делать это mv *(.) "$target"быстро и практично. Однако, если вы делаете это как часть сценария, вы можете вместо этого написать что-то вроде того, что предложили Frxstrem и David Forester mv -t "$target" -- *(.), чтобы лучше обрабатывать угловые случаи, которые могут возникнуть при использовании другими людьми.

Йол
источник
1
Как отметил Дэвид Форестер в моем ответе, mv -t "$TARGET" -- "$SOURCE"/*(.)было бы безопаснее (в случае, если он "$TARGET"начинается с -или не является каталогом). Мне действительно нравится решение Zsh!
Frxstrem
2

Чтобы переместить все, кроме каталогов из 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))

См. Запуск файла Python в терминале .

JFS
источник
@SergiyKolodyazhnyy Я не вижу такого требования в pep-8 и (в соответствии с приведенным там примером) на самом деле все наоборот: import mypackageдоfrom mypackage import ...
jfs
@SergiyKolodyazhnyy не путайте специальный from __future__импорт и обычный from pathlibимпорт.
JFS
Да, похоже, я неправильно понял эту часть. Нет, вы правы, import moduleдолжно быть первым (импорт из библиотеки и сторонних производителей) from module import objectдолжно быть последним (локально / специфично для библиотеки)
Сергей Колодяжный,
0

Я бы использовал

mv *.*

это будет работать до тех пор, пока ваши папки не имеют расширений.


источник