ย้ายทุกไฟล์ที่ไม่ใช่ไดเรกทอรี


14

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

ฉันกำลังคิดเช่น:

mv [*_but_no_dirs] ./other_directory

ดูเหมือนว่าควรมีวิธีง่ายๆในการทำเช่นนี้กับ wildcard *และ regex ...

ใครมีแนวคิดบ้าง


1
ดังนั้นย้ายไฟล์ทั้งหมดในโฟลเดอร์ย่อย แต่ไม่สนใจไฟล์ใด ๆ ในไดเรกทอรีย่อย?
วิลฟ์


2
ใน zsh คุณสามารถทำmv **/*(.) ./other_directory- มีการทุบตีคุณจะต้องหันไปใช้คำสั่งภายนอกเช่นfindแม้ว่า
godlygeek

คำตอบ:


12

Regex ไม่มีส่วนเกี่ยวข้องที่นี่ สัญลักษณ์แทนใน bash (เช่นเชลล์อื่น ๆ ส่วนใหญ่) จับคู่ไฟล์ตามชื่อไฟล์เท่านั้นไม่ได้ยึดตามประเภทไฟล์หรือคุณสมบัติอื่น ๆ มีวิธีหนึ่งที่จะจับคู่ตามประเภท: การเพิ่ม/ที่ส่วนท้ายของรูปแบบทำให้ตรงกับไดเรกทอรีหรือลิงก์สัญลักษณ์ไปยังไดเรกทอรีเท่านั้น ด้วยวิธีนี้คุณสามารถย้ายไดเรกทอรีจากนั้นย้ายสิ่งที่เหลืออยู่และย้ายไดเรกทอรีกลับ - ยุ่งยาก แต่ใช้งานได้

tmp=$(TMPDIR=.. mktemp -d)
mv -- */ "$tmp"
mv -- * "$tmp"/other_directory/
mv "$tmp"/* .
rmdir "$tmp"

findวิธีการมาตรฐานเพื่อให้ตรงกับไฟล์ตามประเภทคือการเรียก

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

ใน zsh คุณสามารถใช้ตัวระบุแบบกลมเพื่อจับคู่ไฟล์ตามประเภท .คัดเลือกตรงกับไฟล์ปกติ; ใช้^/เพื่อจับคู่กับไดเรกทอรีที่ไม่ใช่ทั้งหมดหรือ-^/เพื่อรวมลิงก์สัญลักษณ์ไปยังไดเรกทอรี

mv -- *(.) other_directory/

ในเชลล์ใด ๆ คุณสามารถวนซ้ำได้

for x in *; do
   if ! [ -d "$x" ]; then
     mv -- "$x" other_directory/
   fi
done

8

คุณสามารถใช้สิ่งที่ชอบ

find . -maxdepth 1 \( ! -type d \) -exec sh -c 'mv  "$@" MYDIR' _ {} \;

ครั้งแรกที่เราใช้findเพื่อดูเฉพาะใน directoy ปัจจุบันแล้วเราไม่สนใจไดเรกทอรีโดยใช้! -type d ในที่สุดเราดำเนินการshและย้ายทุกอย่างไปยังปลายทาง dir คุณอาจลอง {} +ตอนท้ายซึ่งจะเร็วขึ้น


2
คำอธิบายเล็กน้อยโปรด ...
เครื่องหมายคำถาม

1
@Questionmark ฉันได้อัปเดตคำตอบและเพิ่มคำอธิบายแล้ว นอกจากนี้ยังควรเยี่ยมชมmywiki.wooledge.org/UsingFind
Valentin Bajrami

ทำไมคุณแนะนำ-exec sh -c 'mv "$@" MYDIR' _ {} \;มากกว่า-exec mv {} MYDIR \;? เพียงเพื่อให้ได้สิ่งที่สามารถปรับปรุงได้โดยการเปลี่ยน\;เป็น+? คุณสามารถทำได้ด้วย-exec mv -t MYDIR {} +แบบฟอร์ม
สกอตต์

@Scott ฉันไม่รู้เกี่ยวกับ-tธง ฉันยังอธิบายในคำตอบว่า+มันเร็วกว่า แต่ไม่ใช่ทุกfindเวอร์ชั่นรองรับ ดังนั้นรหัสข้างต้นค่อนข้างเข้ากันได้กับใด ๆfindหรือเปลือกที่ใช้
Valentin Bajrami

1
@ val0x00ff:“ …โค้ดด้านบนนั้นเข้ากันได้กับทุก ๆfindเชลล์หรือที่ใช้” ทรู แต่เพื่อให้เป็นและทรัพยากรที่ใช้น้อยกว่าfind … -exec mv {} MYDIR \; … -exec sh -c 'mv "$@" MYDIR' _ {} \;
สกอตต์

0

อาจเป็นอันตรายเล็กน้อย แต่

cp * destination/
rm *

เนื่องจากทั้ง cp และ rm จะไม่ทำงานในไดเรกทอรีที่ไม่มีสวิตช์ -r


-1

ฉันอยากจะแนะนำเพียงแค่ทำmv *.* destination/กับปลายทาง / เป็นโฟลเดอร์ที่คุณกำลังจะย้ายไป


2
เช็คเอาท์: unix.stackexchange.com/help/formatting
Jeff Schaller

2
ชื่อไดเรกทอรีสามารถมี 'dot' และชื่อไฟล์สามารถแยกออกได้ (และมักจะทำ) ดังนั้น*.*จะย้ายบางไดเรกทอรีและปล่อยไฟล์บางไฟล์ซึ่งไม่ใช่สิ่งที่ผู้ถามต้องการ
dave_thompson_085

ขออภัย แต่นี่ผิดทั้งหมด มันจะย้ายอะไรก็ได้ที่มีจุดอยู่ในชื่อและจะไม่ย้ายอะไรเลยหากไม่มีใคร จุดไม่ได้มีเฉพาะในไฟล์เท่านั้นและไม่จำเป็นต้องใช้ไฟล์เช่นกันดังนั้นนี่จะเป็นการย้ายการสุ่มเลือกไฟล์และไดเรกทอรี
terdon

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