คุณสามารถใช้รูปแบบการวนรอบขั้นสูงในบางเชลล์เพื่อจับคู่ไฟล์ทั้งหมดในไดเรกทอรียกเว้นการจับคู่รูปแบบเฉพาะ ตัวอย่างเช่นในคำสั่ง 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จะไม่ทำในสิ่งที่คุณต้องการให้ทำ