คุณจะย้ายไฟล์เป็นจำนวนมากในหนึ่งไดเรกทอรีได้อย่างปลอดภัยได้อย่างไร


10

ฉันจะย้ายไฟล์ไปยังไดเรกตอรีโดยที่อาจมีหลายร้อยหรือหลายพันไฟล์ในไดเรคทอรีและคุณอาจไม่แน่ใจว่ามีพหูพจน์อยู่..หรือไม่ คุณจะใช้วิธีใด

วิธีจัดการกับดักจะแตกต่างกันไปบางครั้งเราจะเขียนทับบางครั้งเราต้องปลอดภัยกว่า IO มีความสำคัญเนื่องจากเป็นเซิร์ฟเวอร์ที่ใช้งานจริง แต่ปริมาณที่กำหนดจะเป็นตัวเลือกสำหรับไฟล์ที่ไม่ซ้ำกัน การสงวนสิทธิ์และการประทับเวลา ฯลฯ เป็นสิ่งสำคัญ เรามักจะไม่รู้ว่าข้อมูลคืออะไร

โอ้และmvไม่จำเป็นต้องใช้งานrsync, cpยินดีต้อนรับโซลูชัน

หมายเหตุ: เรากำลังเรียกใช้ CentOS 5.5 เพื่อแจ้งให้เราทราบหากไม่สามารถใช้งานได้เนื่องจากเป็นคุณสมบัติที่ใหม่กว่า ...


ypu ต้องการทำอะไรเกี่ยวกับการหลอก?

@ ฉันขึ้นอยู่กับสถานการณ์หรือไม่ ฉันทำงานที่เว็บโฮสต์ ... มันขึ้นอยู่กับmvว่าเราใส่ใจเกี่ยวกับการอนุรักษ์ในกรณีที่ ... และไม่ว่าเราจะทำการสำรองข้อมูลไว้หรือไม่ คำถามนี้ค่อนข้างเปิด ฉันแค่กำลังมองหาตัวเลือกที่ดีและอาจมีความคิดเห็นเกี่ยวกับว่ามันจะกัดคุณได้อย่างไร
xenoterracide

ฉันคิดว่ามีไฟล์มากเกินไปสำหรับเชลล์ที่จะจัดการmv * ../หรือmv -i * ../?
Michael Mrozek

@Michael ฉันแน่ใจว่ามันแตกต่างกัน ... ในบางกรณีอาจไม่ ในบางกรณีอาจจะ ฉันพยายามจับใจตัวเลือกมากมายสำหรับงานของฉันที่เป็นไปได้
xenoterracide

คำตอบ:


6

ฉันอยากจะแนะนำให้ใช้ rsync จากผู้ปกครอง:

rsync -avPr -b --suffix='-original' child/* .

ซึ่งจะสำรองไฟล์ที่ซ้ำกันที่มีอยู่ทั้งหมดในพาเรนต์ไปยังไฟล์ - ดั้งเดิม


ฉันคิดว่าเป็น-aนัย-r
xenoterracide

@xenoterracide - ใช่คุณ
Tok

@Tok เป็นไปได้ไหมที่จะทำสำเนาเป็นฮาร์ดลิงก์? เพื่อไม่ให้เสีย IO (เช่น-lสำหรับcp)
xenoterracide

@xenoterracide - คุณสามารถใช้-Hหรือตั้ง--hard-linksค่าสถานะสำหรับ rsync เพื่อรักษาลิงก์ถาวร
Tok

1
@xenoterracide - คุณสามารถใช้การ--link-dest=DIRตั้งค่าสถานะเพื่อให้บรรลุพฤติกรรมนี้เป็น: rsync -avP --link-dest=/path/to/src /path/to/src/* /path/to/dest/ซึ่งจะเชื่อมโยงอย่างหนักใน dst / ไฟล์ไม่เปลี่ยนแปลงใด ๆ ระหว่าง src และ src ในกรณีนี้ไฟล์ทั้งหมด --link-dest=/most/recent/backupปกติคุณเห็นธงนี้ใช้เมื่อคุณต้องการสำรองไฟล์ใหม่การเชื่อมโยงโดยไม่คัดลอกข้อมูลของพวกเขาเช่น
Tok

4
cp -bal . ..

สิ่งนี้จะคัดลอกทุกอย่างในไดเรกทอรีปัจจุบันไปยังไดเรกทอรีด้านบนเก็บสิทธิ์ทั้งหมดใช้ hardlinks เพื่อลด IO ถ้าเป็นไปได้และทำซ้ำมันจะสร้างชื่อไฟล์ ~

หลังจากนั้น

rm -rf . ; cd .. ; rmdir <originaldir>;

อาจพบปัญหาไฟล์จำนวนมาก ... แต่ไม่เข้มข้นถึง IO เหมือน rsync
xenoterracide

2

ในตัวอย่างนี้จะย้ายไฟล์จาก '/ parent / old-dir' เป็น '/ parent':

cd /parent

rsync -av --progress old-dir/ .

rm -rf old-dir

ตามกฎ rsync มันจะเข้ามาแทนที่ dups old-dirกับไฟล์ใหม่จาก


1

คุณสามารถลอง

find . -maxdepth 1 -print0 | xargs -I '{}' -r0 mv '{}' ..

ซึ่งจะเขียนทับไฟล์ dupe ด้วยค่ะ

คุณสามารถใช้ mv -u '{}' เพื่อไม่ให้เขียนทับได้หาก dupe in .. เหมือนกันหรือใหม่กว่า


ทำไมท่อถึงพบกับ xargs ทำไมไม่ใช้+
xenoterracide

1
@xenoterracide - นิสัยและการพกพา (เป็นส่วนขยาย GNU) ยิ่งไปกว่านั้นฉันได้ลองแล้วและไม่สามารถหาวิธีส่งพารามิเตอร์ที่สอง..ไปยังmv '{}' +คำสั่งเนื่องจาก + เพิ่งเพิ่มไปยังจุดสิ้นสุด

@ ฉันได้+ อยู่ใน POSIXจริง ๆ แล้วฉันได้รับแจ้งจาก GNU ว่าพบว่ามาสาย
xenoterracide

คุณพูดถูก แต่ฉันยังไม่สามารถหาวิธีใช้ ..

2
@xenoterracide: ด้วย coreutils -exec mv -t .. -- {} +GNU: แบบพกพา: -exec sh -c 'mv -- "$@"' _ {} +.
Gilles 'หยุดความชั่วร้าย'

1

mv -i แจ้งเตือนหากปลายทางมีอยู่เท่านั้น

yes n | mv -i …ย้ายไฟล์ทั้งหมดที่ไม่มีอยู่ในไดเรกทอรีปลายทาง บน FreeBSD และ OSX คุณสามารถย่อให้mv -n …เหลือ

โปรดทราบว่าสิ่งเหล่านี้จะไม่รวมอาร์กิวเมนต์ไดเรกทอรีที่มีไดเรกทอรีที่มีอยู่ในชื่อเดียวกันในไดเรกทอรีปลายทาง


ปัญหาที่แยกต่างหากคือวิธีดำเนินการกับไฟล์ทั้งหมดในไดเรกทอรีปัจจุบัน มีสองปัญหาคือการคว้าไฟล์ทั้งหมด ( *ละเว้นไฟล์ dot) และไม่ทำงานในบรรทัดคำสั่ง บน Linux (หรือมากกว่าปกติด้วย GNU find และ GNU coreutils):

find . -mindepth 1 -maxdepth 1 -exec mv -i -t .. -- {} +

ด้วย GNU ค้นหา แต่ไม่ใช่ coreutils ของ GNU (หรือ coreutils GNU ที่เก่ากว่า):

find . -mindepth 1 -maxdepth 1 -exec sh -c 'mv -i -- "$@" "$0"' .. {} +

portably:

find . -name . -o -exec sh -c 'mv -i -- "$@" "$0"' .. {} -type d -prune

ตามปกติ zsh ทำให้สิ่งต่าง ๆ ง่ายขึ้น มันไม่มีข้อจำกัดความยาวบรรทัดคำสั่งภายในดังนั้นหากคุณใช้mvbuiltin ของมันคุณไม่จำเป็นต้องกังวลเกี่ยวกับเรื่องนั้น และคุณสามารถบอกได้ว่าอย่าเพิกเฉยต่อไฟล์ dot ด้วยตัวระบุDคุณสมบัติแบบกลม ข้อ จำกัด : สิ่งนี้ไม่สามารถใช้ได้กับระบบไฟล์ (ตั้งแต่ zsh 4.3.10)

zmodload zsh/files
mv -i -- *(D) ..

ข้อโต้แย้งมากมาย?
xenoterracide

0

ฉันพูดใน ML ของเรา

mv * ..

เห็นได้ชัดว่ามันไม่ปลอดภัยมาก ... มันจะเขียนทับสิ่งต่าง ๆ อาจมีข้อ จำกัด ที่ฉันไม่เคยพบเจอ


2
หากคุณมีไฟล์จำนวนมากคุณน่าจะได้รับ 'รายการอาร์กิวเมนต์ที่ยาวเกินไปผิดพลาด'

2
-มันอาจจะทำสิ่งที่ไม่ดีถ้าคุณมีชื่อไฟล์ที่ขึ้นต้นด้วย .มันจะไม่จับไฟล์ที่มีชื่อขึ้นต้นด้วย
Gilles 'หยุดความชั่วร้าย'

0

ต่อไปนี้เป็นเทมเพลตหลามที่ฉันเคยใช้เพื่อผลที่ดีในอดีต

#!/usr/bin/env python
#
# Bart Kastermans, www.bartk.nl
#
# rename of collection of files in a directory
import os
import shutil

# only work on files whose name starts with a D
files = [filename for filename in os.listdir ("/Users/kasterma/Music/Audio Hijack/") if filename[0] =="D"]

for filename in files:
    shutil.move (filename, filename [:23] + ".mp3")
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.