คุณสามารถใช้รูปแบบการวนรอบขั้นสูงในบางเชลล์เพื่อจับคู่ไฟล์ทั้งหมดในไดเรกทอรียกเว้นการจับคู่รูปแบบเฉพาะ ตัวอย่างเช่นในคำสั่ง ksh, bash หรือ zsh
shopt -s extglob ## needed in bash only
setopt ksh_glob ## needed in zsh only
mv /source/!(*.bak) /destination
จะย้ายไฟล์ทั้งหมดใน/source
การยกเว้นสำหรับการจับคู่ไฟล์/destination
*.bak
ใน zsh คุณยังสามารถเขียนได้/source/^*.bak
หากคุณเรียกใช้ครั้งแรกsetopt extended_glob
และโดยทั่วไป (ต้องมีอีกครั้งsetopt extended_glob
) /source/*~*.bak
(หรือ/source/a*~*.bak
สำหรับไฟล์ทั้งหมดที่มีชื่อขึ้นต้นด้วยa
ยกเว้น.bak
ไฟล์ ฯลฯ )
Zsh มีคำสั่งคัดลอก / ย้าย / เชื่อมโยงจำนวนมากซึ่งสามารถใช้เพื่อย้ายไฟล์ทั้งหมดยกเว้นไฟล์ที่ตรงกับรูปแบบ ตัวอย่างเช่นคำสั่งต่อไปนี้จะย้ายไฟล์ทั้งหมดยกเว้น*.bak
จาก/source
ถึงtarget
และเพิ่ม.bak
ลงในชื่อไฟล์ในกระบวนการ:
autoload zmv
zmv '/source/(*)~*.bak' '/target/$1.bak'
มีหลายคำสั่งที่เรียกว่าrename
ลอยอยู่รอบ ๆ บน Debian และ Ubuntu /usr/bin/rename
เป็นสคริปต์ Perl ที่ย้ายไฟล์ไปยังชื่อใหม่ที่สร้างโดยนิพจน์ Perl คุณสามารถยกเว้นไฟล์จากการเปลี่ยนชื่อโดยไม่สร้างชื่อใหม่หากไฟล์นั้นจะถูกยกเว้น ตัวอย่างเช่นคำสั่งต่อไปนี้ (ใช้rename
โปรแกรมนี้โดยเฉพาะ) ย้ายไฟล์ทั้งหมดยกเว้น*.bak
จาก/source
เป็น/target
:
rename 's!/source!/target! unless m!\.bak$!' /source/*
คุณสามารถใช้find
คำสั่งเพื่อเลือกไฟล์ที่คุณต้องการย้าย ตัวอย่างเช่นคำสั่งต่อไปนี้จะย้ายไฟล์ปกติทั้งหมดยกเว้น*.bak
ใน/source
หรือไดเรกทอรีย่อยเข้า/target
(โปรดทราบว่าโครงสร้างไดเรกทอรีถูกยุบ):
find /source -type f \! -name '*.bak' -exec mv {} /target/ \;
หรือ (มีประสิทธิภาพมากขึ้นหากมีไฟล์จำนวนมากที่จะย้าย)
find /source -type f \! -name '*.bak' -exec sh -c 'mv "$@" "$0"' /target/ {} +
rsync
เป็นลักษณะทั่วไปcp
และscp
มีกฎการรวม / ไม่รวมที่มีประสิทธิภาพมาก ตัวอย่างเช่นคำสั่งดังต่อไปนี้คัดลอกไฟล์ทั้งหมดยกเว้น*.bak
ใน/source
หรือไดเรกทอรีย่อยเข้า/target
เคารพโครงสร้างไดเรกทอรี:
rsync -a --exclude '*.bak' /source/ /target/
pax
คือ (เหนือสิ่งอื่นใด) cp
ในสเตียรอยด์ กฎการยกเว้นของมันไม่ได้มีประสิทธิภาพเทียบเท่ากับ rsync แต่ก็มีความสามารถเพิ่มเติมในการเปลี่ยนชื่อไฟล์เมื่อมีการคัดลอก หากคุณเปลี่ยนชื่อไฟล์เป็นสตริงว่างเปล่ามันจะถูกแยกออกจากสำเนา ตัวอย่างเช่นคำสั่งต่อไปนี้คัดลอกไฟล์ทั้งหมดยกเว้น*.bak
ใน/source
หรือไดเรกทอรีย่อยลงใน/target
และเปลี่ยนชื่อไฟล์เป็น.bak
ในการผ่าน
cd /source && pax -rw -pp -s '/.*\.bak$//' -s '/$/.bak/' . /target/
ตัวอย่างข้างต้นมีผลข้างเคียงที่โชคร้ายของการสร้างไดเรกทอรีfoo.bak
ที่สามารถหลีกเลี่ยงได้โดยการรวมfind
กับpax
:
{ cd /source && find . -type f; } | \
pax -rw -pp -s '/.*\.bak$//' -s '/$/.bak/' /target/
mv file1 file2 /path/to/destination
จะไม่ทำในสิ่งที่คุณต้องการให้ทำ