จะย้ายเฉพาะไฟล์ต่าง ๆ ในโฟลเดอร์ปัจจุบันไปยังโฟลเดอร์ย่อยได้อย่างไร?


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ไม่มีไดเรกทอรีหรือการจับคู่เริ่มต้นด้วย-) และมีประสิทธิภาพมากขึ้น (เพราะไม่ทำให้กระบวนการย่อยใหม่เกิดขึ้นสำหรับไฟล์ที่ตรงกันทุกไฟล์)
David Foerster

@DavidFoerster ขอบคุณอัปเดต (ยังได้เรียนรู้สิ่งใหม่วันนี้!)
Frxstrem

5

ฉันคิดว่าคุณต้องการ mv เฉพาะไฟล์ของคุณแรกไปที่ไดเรกทอรีของคุณและใช้คำสั่งนี้แทนที่ $ TARGET ด้วยเส้นทางไดเรกทอรีเป้าหมายของคุณ หากคุณต้องการที่จะคัดลอกไฟล์ของคุณแทนที่ด้วยmvcp

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ไม่ได้ป้องกันการเรียกซ้ำ
Martin Thornton

@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- รายการของไฟล์ที่เราสร้างขึ้น

เพื่อความสะดวกในการอ่านและการใช้งานทั่วไปเราสามารถเขียนสคริปต์นี้เป็นสคริปต์ไพ ธ อนทั่วไปซึ่งใช้สองข้อโต้แย้ง - ไดเรกทอรีต้นทางและไดเรกทอรีย่อยปลายทาง

#!/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

นี่เป็นอีกวิธีการ
jfs

3

หากคุณกำลังใช้ zsh แทนที่จะทุบตีคุณสามารถทำได้:

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

(.)ในตอนท้ายที่เรียกว่ารอบคัดเลือก glob; .ภายในโดยเฉพาะหมายถึงเพียงตรงกับไฟล์ปกติ

การทำ a mv *(.) "$target"นั้นรวดเร็วและใช้งานได้จริง อย่างไรก็ตามหากคุณทำเช่นนี้เป็นส่วนหนึ่งของสคริปต์คุณอาจต้องการพิจารณาเขียนสิ่งที่ Frxstrem และ David Forester แนะนำmv -t "$target" -- *(.)แทนเพื่อจัดการกับกรณีมุมที่อาจเกิดขึ้นในการใช้งานของผู้อื่น


1
ดังที่ David Forester ชี้ให้เห็นในคำตอบของฉัน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))

ดูเล่นหลามไฟล์ในเทอร์มิ


@SergiyKolodyazhnyy ฉันไม่เห็นความต้องการดังกล่าวใน pep-8 และ (ตามตัวอย่างมี) เป็นจริงตรงข้ามที่แน่นอน: import mypackageก่อนfrom mypackage import ...
jfs

@SergiyKolodyazhnyy ไม่สับสนfrom __future__การนำเข้าพิเศษและfrom pathlibการนำเข้าทั่วไป
jfs

ใช่ดูเหมือนว่าฉันได้อ่านส่วนนั้นผิด ไม่ถูกต้องimport moduleควรเป็นอันดับแรก (ซึ่งเป็นห้องสมุดและการนำเข้าจากบุคคลที่สาม) from module import objectควรเป็นครั้งสุดท้าย (เฉพาะในท้องถิ่น / ห้องสมุด)
Sergiy Kolodyazhnyy

0

ฉันจะใช้

mv *.*

สิ่งนี้จะทำงานได้ตราบใดที่โฟลเดอร์ของคุณไม่มีส่วนขยาย

โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.