ย้ายไฟล์ทั้งหมดยกเว้นหนึ่งไฟล์


155

ฉันจะย้ายไฟล์ทั้งหมดยกเว้นหนึ่งไฟล์ได้อย่างไร ฉันกำลังมองหาบางสิ่งที่ชอบ:

'mv ~/Linux/Old/!Tux.png ~/Linux/New/'

ที่ผมย้ายสิ่งเก่าที่จะ -folder Tux.pngสิ่งใหม่ยกเว้น ! -sign แสดงถึงการปฏิเสธ มีเครื่องมือสำหรับงานบ้างไหม?

คำตอบ:


142

หากคุณใช้ bash และมีการextglobตั้งค่าตัวเลือกของเชลล์

mv ~/Linux/Old/!(Tux.png) ~/Linux/New/

1
ฉันพบข้อผิดพลาดบางอย่างเมื่อฉันทดสอบคำสั่งสำหรับหลายรายการ: mv ~ / Linux / Old /! (Tux.png Tux1.png Tux2.png) ~ / Linux / ใหม่ / มันว่างทั้งไดเรกทอรีเก่า เกิดอะไรขึ้น?
LéoLéopold Hertz 준영

5
@UnixBasics ลอง: ~ / Linux / Old /! (Tux.png | Tux1.png | Tux2.png)
Juliano

@Juliano คำสั่งเด็ดมาก! มีการดำเนินการทางคณิตศาสตร์มากขึ้นเช่น OR และ XOR หรือไม่? ฉันถือว่าท่อสำหรับและ
LéoLéopold Hertz 준영


@Juliano ฉันค่อนข้างสับสนกับรูปแบบเช่น: mv ~ / Linux /? (Tux * .png) ~ / Linux / ใหม่ / mv ~ / Linux / + (Tux * .png) ~ / Linux / ใหม่ / ในอดีต ฉันต้องการย้าย 0-1 Tux -photo ในตอนหลังฉันต้องการย้ายภาพทักซ์ 1-n พวกเขาย้ายทุกคน ทำไม? เป็นไปได้ไหมที่จะย้ายภาพถ่ายตามจำนวนที่กำหนด?
LéoLéopold Hertz 준영

97

ใส่ต่อไปนี้เพื่อ. bashrc ของคุณ

shopt -s extglob

มันขยาย regexes จากนั้นคุณสามารถย้ายไฟล์ทั้งหมดยกเว้นหนึ่งไฟล์โดย

mv !(fileOne) ~/path/newFolder

ข้อยกเว้นเกี่ยวกับคำสั่งอื่น ๆ

โปรดทราบว่าในการคัดลอกไดเรกทอรีแฟลชไปข้างหน้าไม่สามารถใช้ในชื่อตามที่สังเกตเห็นในเธรดทำไมถึงมี extglob ยกเว้นการแตกยกเว้นเงื่อนไข? :

cp -r !(Backups.backupdb) /home/masi/Documents/

ดังนั้นBackups.backupdb/ผิดที่นี่ก่อนการปฏิเสธและฉันจะไม่ใช้มันในการย้ายไดเรกทอรีเนื่องจากความเสี่ยงของการใช้ผิดแล้ว globs กับคำสั่งอื่น ๆ และข้อยกเว้นอื่น ๆ ที่เป็นไปได้


3
นี่เป็นคำตอบที่ถูกต้องจริงๆ ฉันถูกแบนผิด โชคดีที่ฉันใช้มันในโฟลเดอร์ที่มีไฟล์เพียงไม่กี่ไฟล์ นี่คือข้อมูลเพิ่มเติมเกี่ยวกับวิธีที่ Masi แสดง: wiki.bash-hackers.org/syntax/patternไปที่ "ภาษารูปแบบขยาย" และคุณจะพบข้อมูลเพิ่มเติมเกี่ยวกับสิ่งนี้ ขอบคุณ @ paul-whittaker สำหรับการชี้ปัญหา
mimoralea

นี่เป็นคำตอบเก่า แต่ก็ยังใช้ได้ ฉันใช้ Ubuntu 18 และดูเหมือนว่าจะเปิดใช้งาน extglob ตามค่าเริ่มต้น (ฉันไม่ได้ซื้อสินค้า) ผมใช้คำสั่งต่อไปที่จะย้ายไฟล์ทั้งหมดในไดเรกทอรีปัจจุบันไปยังที่เก็บที่ยังอยู่ในไดเรกทอรีนี้ไม่รวมถึงโฟลเดอร์เก็บอื่น ๆ ใด ๆ : mv !(arc*) archive_190629b
TonyG

70

ฉันจะไปกับวิธีการค้นหา & xargs แบบดั้งเดิม:

find ~/Linux/Old -maxdepth 1 -mindepth 1 -not -name Tux.png -print0 | 
    xargs -0 mv -t ~/Linux/New

-maxdepth 1ทำให้ไม่ค้นหาซ้ำ หากคุณสนใจเฉพาะไฟล์คุณสามารถพูด-type fได้ -mindepth 1ทำให้ไม่รวม~/Linux/Oldเส้นทางของตัวเองลงในผลลัพธ์ ทำงานร่วมกับชื่อไฟล์ใด ๆ รวมถึงที่มีการขึ้นบรรทัดใหม่

หนึ่งความคิดเห็นตั้งข้อสังเกตว่า-tตัวเลือกmv เป็นส่วนขยายของ GNU สำหรับระบบที่ไม่มี

find ~/Linux/Old -maxdepth 1 -mindepth 1 -not -name Tux.png \
    -exec mv '{}' ~/Linux/New \;

1
เพิ่มขึ้นเนื่องจากมันส่งเสริมการเรียนรู้เครื่องมืออันทรงพลัง หมายเหตุสำหรับไฟล์ที่มีช่องว่างนี้จะไม่ทำงาน พิจารณา "find -print0 | xargs -0" หรือนำหน้า xargs: "find [สิ่งที่คุณพูด] -exec mv -t {} ~ / Linux / New \;"
JasonSmith

หากคำสั่ง mv ของคุณไม่มีตัวเลือก -t ให้ใช้ "find ... -exec mv {} Linux / New \;" หรือ "ค้นหา ... | xargs -I {} mv {} Linux / ใหม่" ตัวเลือก -t น่าจะเป็นส่วนขยายของ GNU ซึ่งใช้ได้สำหรับ Linux แต่อาจไม่ใช่ที่อื่น
Rob Kennedy

jhs โอ้ฉันล้มเหลว ฉันคิดว่า xargs แยกที่บรรทัดใหม่ แต่ไม่ได้อยู่ในช่องว่าง ดูเหมือนว่าฉันสับสนกับ "อ่าน" :) ไม่สามารถแก้ไขได้
Johannes Schaub - litb

ขอบคุณมากสำหรับเคล็ดลับสุดยอด! ฉันจะเลือก sth เพราะมันตั้งเป้าหมายไว้ อย่างไรก็ตามฉันสามารถรู้สึกถึงประโยชน์ของคำสั่งของคุณในภายหลังดังนั้นฉันจึงต้องเลือกวิธี "find and xargs" มันเป็นเพียงหิน ขอบคุณ :)
LéoLéopold Hertz 준영

วิธีการที่ซับซ้อน คำตอบของ Masi นั้นสมบูรณ์กว่าง่ายกว่าและถูกต้องกว่าเดิม
637338

30

วิธีที่รวดเร็วคือการแก้ไขชื่อไฟล์ tux เพื่อให้คำสั่งย้ายของคุณไม่ตรงกัน

ตัวอย่างเช่น:

mv Tux.png .Tux.png

mv * ~/somefolder

mv .Tux.png Tux.png

อย่าใช้ " . " เนื่องจากจะทำการย้ายไฟล์ที่มี "." เท่านั้น ในชื่อ. แค่ "*" ก็เพียงพอแล้ว
Juliano

1
หากคุณเปลี่ยนเป็น * มันจะลบไฟล์ที่ถูกเปลี่ยนชื่อของคุณเช่นกัน
John T

6
@John T: ไม่ * glob ไม่ตรงกับไฟล์ที่ขึ้นต้นด้วยจุด
Bill Karwin

นี่คือคำตอบที่ดีที่สุด ไม่จำเป็นต้องแก้ไขหรือแสดงความคิดเห็นคำตอบนี้ 100 คะแนน ขอบคุณมาก. ทำได้ดี!
Steve K

23

ฉันคิดว่าวิธีที่ง่ายที่สุดที่จะทำคือกับ backticks

mv `ls -1 ~/Linux/Old/ | grep -v Tux.png` ~/Linux/New/

แก้ไข:

ใช้เครื่องหมายแบ็กสแลชที่มี ls แทนเพื่อป้องกันการใช้กับนามแฝงนั่นคือ ls ส่วนใหญ่จะใช้นามแฝงเป็น ls --color

mv `\ls -1 ~/Linux/Old/ | grep -v Tux.png` ~/Linux/New/

ขอบคุณ @Arnold Roa


1
คุณช่วยอธิบายได้ไหมว่าทำไมถึงใช้ที่grep -vนั่น?
LéoLéopold Hertz 준영

1
ตัวเลือก -v ใน grep ไม่รวมผลลัพธ์เหมือนกับการใช้ทุกอย่างยกเว้น Tux.png
Rohail Abbas

1
นี่เป็นวิธีที่เข้าใจง่าย แต่คำตอบข้างต้นดีกว่า หากคุณกำลังเขียนบทเช่นนี้จะทำให้คุณต้องอยู่ในไดเรกทอรีที่ถูกต้อง ..
nJGL

@nJGL เราสามารถให้เส้นทางที่แน่นอนได้ที่นี่ฉันใช้ homedirectory (~) เนื่องจากคำถามมี
Rohail Abbas

@RohailAbbas ยุติธรรมพอ ✌️
nJGL

14

สำหรับ bash คำตอบของ sthนั้นถูกต้อง นี่คือไวยากรณ์zsh (เชลล์ที่ฉันเลือก):

mv ~/Linux/Old/^Tux.png ~/Linux/New/

ต้องการEXTENDED_GLOBตัวเลือกเชลล์ที่จะตั้งค่า


3
ถ้าเราต้องการยกเว้นสองไฟล์
mpen

13

ฉันคิดว่านี่เป็นบิตที่ปลอดภัยและง่ายขึ้นสำหรับการย้ายแบบง่าย ๆ ที่ไม่รวมไฟล์หรือไดเรกทอรี

ls -1 | grep -v ^$EXCLUDE | xargs -I{} mv {} $TARGET

นี่เป็นทางออกที่ดีที่สุดสำหรับ Busybox / ASH
Stuart Cardall

1
สิ่งนี้ใช้ได้กับฉันในสถานการณ์ที่ฉันต้องย้ายไฟล์ทั้งหมดยกเว้นโฟลเดอร์เพียงไม่กี่โฟลเดอร์ไปยังไดเรกทอรีอื่น
Umar Hayat

-lตัวเลือกในการlsจะรวมถึงข้อมูลจำนวนมากที่ไม่เกี่ยวข้องในบรรทัดคำสั่งและส่งผลให้เกิดความล้มเหลวของคำสั่ง mv
jdhao

5

ต่อไปนี้ไม่ใช่วิธีการรับประกัน 100% และไม่ควรพยายามเขียนสคริปต์ แต่บางครั้งมันก็ดีพอสำหรับการใช้งานเชลล์แบบโต้ตอบได้อย่างรวดเร็ว ไฟล์ไฟล์ glob เหมือน

[abc]*

(ซึ่งจะจับคู่ไฟล์ทั้งหมดที่มีชื่อขึ้นต้นด้วย a, b หรือ c) สามารถคัดค้านได้โดยการใส่อักขระ "^" ก่อนเช่น

[^abc]*

บางครั้งฉันใช้สิ่งนี้เพื่อไม่จับคู่ไดเรกทอรี "lost + found" เช่น:

mv /mnt/usbdisk/[^l]* /home/user/stuff/.

แน่นอนถ้ามีไฟล์อื่น ๆ ที่ขึ้นต้นด้วย l ฉันต้องประมวลผลไฟล์เหล่านั้นในภายหลัง


4
mv `find Linux/Old '!' -type d | fgrep -v Tux.png` Linux/New

คำสั่ง find แสดงรายการไฟล์ปกติทั้งหมดและคำสั่ง fgrep จะกรอง Tux.png ใด ๆ backticks บอก mv เพื่อย้ายรายการไฟล์ผลลัพธ์


4
ไม่เคยประเมินผล find เป็นอาร์กิวเมนต์สำหรับคำสั่งอื่น สิ่งเลวร้ายจะเกิดขึ้น คุณอาจเพิ่งสร้างช่องโหว่ ใช้ find -print0 | เสมอ xargs -0 สร้างหรือค้นหา -exec
Juliano

3

แล้วคุณย้ายทุกอย่างในโฟลเดอร์ไปได้อย่างไรแล้วแค่ย้าย Tux.png กลับมา?

ฉันไม่สามารถนึกถึงไวยากรณ์ของเชลล์ที่จะพูดว่า "ทุกอย่างยกเว้น ... " ได้ทันที


3
ls ~/Linux/Old/ | grep -v Tux.png | xargs -i {} mv ~/Linux/New/'

1
ดูเหมือนว่าคำสั่งนี้จะหายไปส่วนหนึ่งและไม่ทำงานในคอมพิวเตอร์ของฉัน ls ~/Linux/Old/ | grep -v Tux.png | xargs -I{} mv {} ~/Linux/New/ทำงานแทน
Katherine Chen

3

เกี่ยวกับ:

mv $(echo * | sed s:Tux.png::g) ~/Linux/New/

คุณต้องอยู่ในโฟลเดอร์แม้ว่า



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