ฉันจะย้ายไฟล์ทั้งหมดในไดเรกทอรีย่อยซ้ำไปยังไดเรกทอรีเดียวได้อย่างไร


10

ฉันพยายามรวบรวมไฟล์ทั้งหมดภายใต้ไดเรกทอรีปัจจุบันและไดเรกทอรีย่อยทั้งหมดไปยังไดเรกทอรีเดียว ฉันกำลังลองทำสิ่งต่อไปนี้

find -type f -exec mv {} collection/{} \; 

คำสั่งดังกล่าวจะไม่ทำงานเพราะที่สอง{}ให้เส้นทางเต็มฉันจะรวบรวมไฟล์ทั้งหมดได้อย่างไร

คำตอบ:


14

ถอด{}จากmv, mvจะใช้มันเป็นไดเรกทอรีเป้าหมายละเลยไดเรกทอรีผู้ปกครอง:

find -type f -exec mv {} collection/ \;

โอ้ที่ไม่ได้เกิดขึ้นกับฉัน ขอบคุณ :)
Bunny Rabbit

อย่างที่ฉันพูดในคำตอบของคำถามนี้อาจเป็นความคิดที่ไม่ดี บางทีการใช้อาร์กิวเมนต์-maxdepth 1อาจช่วยได้
loevborg

ลองคิดดูสิฉันอ่านคำถามของคุณผิด :) ขอโทษ
loevborg

@loevborg: ฉันได้เพิ่ม "ซ้ำ" ลงในชื่อตอนนี้ ถ้ายังมีความสับสนโปรดแก้ไขและปรับปรุงให้ดีขึ้น :)
Lekensteyn

1
ความแตกต่างที่รวดเร็วกว่าของคำตอบนี้คือfind -type f -print0|xargs -0r mv -it colection/
hildred

5

แทนที่จะใช้find(ซึ่งทำงานได้ดี) คุณสามารถใช้เชลล์ด้วยเหตุนี้

สมมติว่าคุณต้องการไฟล์ทั้งหมดจาก $ PWD ถึง $ DEST ความพยายามตามธรรมชาติจะเป็น:

mv $PWD/* $DEST

มันทำงานอย่างไร นิพจน์ "$ PWD / *" ขยายเป็นชื่อของไฟล์ทั้งหมดในไดเรกทอรีนั้น คุณสมบัติเปลือกนี้เรียกว่า "globbing" อาร์กิวเมนต์สุดท้ายของmvคือไดเร็กทอรีปลายทาง หากคุณมีไฟล์จำนวนมากสิ่งนี้จะไม่ทำงานเนื่องจากความยาวของบรรทัดคำสั่งมี จำกัด

แต่วิธีการแก้ปัญหามีปัญหาที่มันละเว้นไฟล์ dot - หรือไฟล์ "ซ่อน" ไฟล์และไดเรกทอรีที่ชื่อขึ้นต้นด้วย "." ในการแก้ปัญหานี้คุณต้องบอกให้เปลือกของคุณรวม dotfiles ไว้ด้วย เมื่อต้องการทำเช่นนี้ใช้

shopt -s dotglob

เมื่อใช้bash(และคุณอาจใช้bashจนกว่าคุณจะเปลี่ยนค่าเริ่มต้น) ในเปลือกนี้คำสั่งดังกล่าวจะทำงานสำหรับ dotfiles เช่นกัน

นอกจากนี้zshคุณยังมีตัวเลือกให้เลือกแบบนี้เป็นกรณี ๆ ไป เมื่อต้องการทำเช่นนี้ใส่

setopt extendedglob

.zshrcในของคุณ จากนั้นคุณสามารถใช้

mv $PWD/*(D) $DEST

เพื่อย้ายไฟล์ทั้งหมดรวมถึง dotfiles ("D" มีผลต่อการเปิดใช้งานตัวเลือก "GLOB_DOTS" ชั่วคราว)

ตอนนี้คำถามเดิมคือการย้ายไฟล์ปกติทั้งหมด (ไม่ใช่ไดเรกทอรี) จากไดเรกทอรีย่อยทั้งหมดและไดเรกทอรีย่อยของพวกเขาไปยังไดเรกทอรีเดียว สามารถทำได้ด้วยzsh:

mv $PWD/**/*(D.)

ที่นี่การแสดงออก**/*ทำให้ globber ลงไปซ้ำในไดเรกทอรีย่อย Dหมายถึง "ยังเลือก dotfiles' นั้น.หมายถึง 'เพียงเลือกไฟล์ปกติไม่ไดเรกทอรี'


ดีฉันอยากจะ recurse ลงในทุกไดเรกทอรีย่อยเกินไป แต่ต้องขอบคุณทางข้อมูลที่เป็นประโยชน์ใด ๆ เจอสถานการณ์นี้ด้วยหลายครั้ง :)
Bunny กระต่าย

อันที่จริงการค้นหานั้นไม่ได้เกินขีด จำกัด สำหรับสิ่งนี้ globbing จะเลือกการแข่งขันทั้งหมดไม่ใช่แค่ไฟล์เท่านั้น หากคุณกังวลเกี่ยวกับประสิทธิภาพคุณสามารถใช้สิ่งfind -type f -exec mv -t collection/ {} +ต่อไปนี้: ศึกษาหน้าคู่มือเกี่ยวกับวิธีการทำงาน
Lekensteyn

Lekensteyn คุณพูดถูก ฉันปรับปรุงคำตอบทันทีที่ฉันเข้าใจคำถาม
loevborg

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