มีข้อได้เปรียบอะไรบ้างในการระบุ './' ใน a for for loop โดยใช้ glob?


10

ผมก็รู้สึกว่ามันอาจจะปลอดภัยในการใช้เมื่อค้นหาไฟล์ที่ลงท้ายด้วย./*.fastq .fastqยกตัวอย่างเช่นจะป้องกันไม่ให้จับไฟล์./ .fastqเห็นได้ชัดว่ามันผิดอย่างที่แสดงในตัวอย่างด้านล่าง:

TMP_DIR=$(mktemp --directory)
mkdir -p ${TMP_DIR}
(cd ${TMP_DIR}
 touch {a,b,c,}.fastq
 ls -a
 echo ""

 echo "# match all:"
 for f in *.fastq ; do
     echo "${f}"
 done
 echo ""

 echo "# with ./:"
 for f in ./*.fastq ; do
     echo "${f}"
 done
)
rm -rf ${TMP_DIR}
.
..
a.fastq
b.fastq
c.fastq
.fastq

# match all:
a.fastq
b.fastq
c.fastq

# with ./:
./a.fastq
./b.fastq
./c.fastq

ทั้ง*.fastqมิได้ตรงกับไฟล์./*.fastq .fastqดังนั้นฉันจึงสงสัยว่าตอนนี้มีจุดใดบ้างที่ใช้./*.fastqที่นี่หรือ./*โดยทั่วไป?


1
จุดปกติ./*คือเพื่อให้แน่ใจว่าชื่อที่ขึ้นต้นด้วย-จะไม่ถือว่าเป็นตัวเลือก
Charles Duffy

คำตอบ:


15

นั่นเป็นครั้งแรกที่พฤติกรรมของตัวแทนที่น่าแปลกใจเนื่องจากคำอธิบายของ*อักขระตัวแทนกล่าวว่า:

จับคู่สตริงใด ๆ รวมถึงสตริง null

... จนกว่าคุณจะรู้ว่าช่วงเวลานั้นค่อนข้างพิเศษเมื่อตัวละครตัวแรกของชื่อไฟล์ ข้อความเกริ่นนำในภาษา3.5.8 Filename Expansionบอกว่า:

เมื่อใช้รูปแบบสำหรับการขยายชื่อไฟล์อักขระ '.' ที่จุดเริ่มต้นของชื่อไฟล์หรือทันทีหลังจากเครื่องหมายทับจะต้องจับคู่อย่างชัดเจนเว้นแต่ว่าตัวเลือกเปลือก dotglob ตั้งค่า

"รูปแบบการใช้งาน" ของสัญลักษณ์แทนคำนำหน้าด้วย./จะมีประโยชน์สำหรับการจัดการชื่อด้วยเครื่องหมายนำหน้าในเปลือก bashดังที่ผู้ขับเหล็กแสดงความคิดเห็น จะไม่มีผลกับการขยาย wildcard / ชื่อไฟล์ แต่ทำให้ปลอดภัย / ง่ายกว่าในการจัดการชื่อไฟล์เมื่อคุณอ้างถึงหากพวกเขาเริ่มต้นด้วยตัวอักษรที่โปรแกรมเหล่านั้นอาจตีความผิดเป็นตัวเลือก ตัวอย่างเช่น:

# I want a file named `-n`
$ touch -n
touch: invalid option -- 'n'
Try 'touch --help' for more information.
$ touch -- -n
### ok
$ touch ./-n
### ok

... และตอนนี้ฉันมีไฟล์ชื่อ-nแล้วถ้าฉันวนไปวนมาด้วย wildcard:

for file in *n
do
  echo "$file"
done

... ฉันไม่ออกเลย!

แต่ถ้าผมคำนำหน้าสัญลักษณ์แทนด้วย./,

for file in ./*n
do
  echo "$file"
done
./-n

... ฉันเห็นชื่อไฟล์

นี่เป็นตัวอย่างง่ายๆสำหรับวัตถุประสงค์ในการสาธิต ดูเพิ่มเติมทำไม printf ถึงดีกว่า echo ด้วยเหตุผลนี้และอื่น ๆ ยูทิลิตี้อื่น ๆ จะได้รับการสะดุดโดยตัวเลือกอื่น ๆ ดังนั้นจึงเป็นการดีกว่าถ้าจะแสดงชื่อไฟล์ให้กับสาธารณูปโภคอย่างปลอดภัยที่สุด หากคุณไม่ได้ใส่ไวลด์การ์ดไว้ในชื่อ "หนี" คุณจะต้อง "ป้องกัน" ยูทิลิตี้ของคุณด้วยวิธีอื่น หนึ่งทั่วไปหนึ่งคือการส่งสัญญาณการสิ้นสุดของตัวเลือกด้วย--เช่น

for file in *n
do
  mv -- "$file" backup/"$file"
done

... ซึ่งจะปลอดภัยผ่าน-nชื่อไฟล์ไปยังmv(เท่าที่เห็นภายใต้set -x):

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