Як перемістити лише файли в поточній папці до підпапки?


9

Мені не потрібно переміщувати папки, лише файли.

Я спробував, mv *але ця команда також переміщує папки.

Відповіді:


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)

2
find ... -exec mv -t "$TARGET_DIR" -- '{}' +було б безпечнішим (у випадку, якщо $TARGET_DIRнемає каталогу, або збіг починається з -) та більш ефективним (оскільки він не породить новий підпроцес для кожного відповідного файлу).
Девід Фоерстер

@DavidFoerster Спасибі, оновлено (також дізнався сьогодні щось нове!)
Frxstrem

5

Я думаю, що ви хочете, щоб mv використовували лише ваші файли. Спочатку перейдіть до каталогу та скористайтеся цією командою, замініть $ 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 дякую за вашу пропозицію .. я відредагую свою відповідь ...
Emalsha Rasad

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 та Девід Форестер 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 у терміналі .


@SergiyKolodyazhnyy Я не бачу такої вимоги в pep-8, і (згідно з прикладом там) насправді import mypackagefrom mypackage import ...
якраз

@SergiyKolodyazhnyy не плутати спеціальний from __future__імпорт та звичайний from pathlibімпорт.
jfs

Так, схоже, я неправильно прочитав цю частину. Ні, ви праві, import moduleмає бути першим (це імпорт бібліотеки та третіх сторін), from module import objectповинен бути останнім (місцева / бібліотека)
Сергій Колодяжний

0

Я б користувався

mv *.*

це працюватиме до тих пір, поки у ваших папках не буде розширень.

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.