ความแตกต่างระหว่างไฟล์ grep apple และไฟล์ grep“ apple” คืออะไร?


22

ความแตกต่างระหว่างgrep apple fileและgrep "apple" fileคืออะไร? การใส่เครื่องหมายคำพูดทำอะไร? ทั้งคู่ดูเหมือนจะทำงานและทำสิ่งเดียวกัน (แสดงบรรทัดเดียวกัน)

คำตอบ:


45

เครื่องหมายอัญประกาศมีผลต่ออักขระที่เชลล์ของคุณพิจารณาเป็นพิเศษและมีความหมายทางไวยากรณ์ ในตัวอย่างของคุณสิ่งนี้ไม่ได้สร้างความแตกต่างเพราะappleไม่มีอักขระดังกล่าว

แต่พิจารณาอีกตัวอย่างหนึ่ง: grep apple tree fileจะค้นหาคำappleในไฟล์treeและfileในขณะที่grep "apple tree" fileจะค้นหาคำในไฟล์apple tree fileเครื่องหมายคำพูดบอกว่าทุบตีว่าคำในพื้นที่"apple tree"ไม่ได้เริ่มพารามิเตอร์ใหม่ แต่จะต้องเป็นส่วนหนึ่งของพารามิเตอร์ปัจจุบัน grep apple\ tree fileจะให้ผลลัพธ์ที่เหมือนกันเพราะ\บอกให้ทุบตีเพื่อเพิกเฉยต่อความหมายพิเศษของตัวละครต่อไปนี้และปฏิบัติต่อมันอย่างแท้จริง


2
นอกจากนี้ยังสามารถมองเห็นได้ด้วยอักขระตัวแทน ถ้าคุณทำgrep a*b equations.txtแล้วมันจะค้นหาa*bเว้นแต่จะมีไฟล์ในไดเรกทอรีปัจจุบันเริ่มต้นด้วย, และลงท้ายด้วย b ในกรณีนี้ (เพราะ (ba) sh จะขยายชื่อไฟล์ในบรรทัดคำสั่ง) grep จะถูกเรียกด้วย พารามิเตอร์ที่แตกต่างกันอย่างสมบูรณ์ทำให้ได้ผลลัพธ์ที่ต่างกัน นี่เป็นปัญหาที่พบได้บ่อยกว่าเนื่องจากคำสั่งเช่นfind . -name *.txtนั้นจะส่งผลให้เกิดพฤติกรรมที่ไม่คาดคิดหากมีไฟล์ txt ในไดเรกทอรีปัจจุบัน มันจะดีกว่าที่จะใช้คำพูดในกรณีนี้
SztupY

4
อีกจุดสำคัญคือความแตกต่างระหว่างคำพูดสองครั้ง ( ") และคำพูดเดียว ( ') อัญประกาศเดี่ยวป้องกันการตีความของอักขระบางตัวเช่นใน$ขณะที่เครื่องหมายคำพูดคู่อนุญาตการตีความ เช่นgrep '${USER}'จะค้นหาข้อความ${USER}ในขณะที่grep "${USER}"จะค้นหาข้อความที่ตัวแปรUSERมี (เช่นjohnstacen)
Paddy Landau

23

อัญประกาศคู่อนุญาตให้มีการประเมินราคาอัญประกาศเดี่ยวป้องกันการประเมินผลไม่มีเครื่องหมายอัญประกาศอนุญาตให้มีการขยายสัญลักษณ์แทนเมื่อใช้บนบรรทัดคำสั่ง ในฐานะที่เป็นตัวอย่างที่วางแผนไว้:

[user@work test]$ ls .
A.txt B.txt C.txt D.cpp

# The following is the same as writing echo 'A.txt B.txt C.txt D.cpp'
[user@work test]$ echo *
A.txt B.txt C.txt D.cpp

[user@work test]$ echo "*"
*

[user@work test]$ echo '*'
*

# The following is the same as writing echo 'A.txt B.txt C.txt'
[user@work test]$ echo *.txt
A.txt B.txt C.txt

[user@work test]$ echo "*.txt"
*.txt

[user@work test]$ echo '*.txt'
*.txt

[user@work test]$ myname=is Fred; echo $myname
bash: Fred: command not found

[user@work test]$ myname=is\ Fred; echo $myname
is Fred

[user@work test]$ myname="is Fred"; echo $myname
is Fred

[user@work test]$ myname='is Fred'; echo $myname
is Fred

การทำความเข้าใจวิธีการทำงานของคำพูดเป็นหัวใจสำคัญในการทำความเข้าใจ Bash ตัวอย่างเช่น:

# for will operate on each file name separately (like an array), looping 3 times.
[user@work test]$ for f in $(echo *txt); do echo "$f"; done;
A.txt
B.txt
C.txt

# for will see only the string, 'A.txt B.txt C.txt' and loop just once.
[user@work test]$ for f in "$(echo *txt)"; do echo "$f"; done;
A.txt B.txt C.txt

# this just returns the string - it can't be evaluated in single quotes.
[user@work test]$ for f in '$(echo *txt)'; do echo "$f"; done;
$(echo *txt)

คุณสามารถใช้อัญประกาศเดี่ยวเพื่อส่งคำสั่งผ่านตัวแปร เครื่องหมายคำพูดเดี่ยวจะป้องกันการประเมินผล เครื่องหมายคำพูดคู่จะประเมิน

# This returns three distinct elements, like an array.
[user@work test]$ echo='echo *.txt'; echo $($echo)
A.txt B.txt C.txt

# This returns what looks like three elements, but it is actually a single string.
[user@work test]$ echo='echo *.txt'; echo "$($echo)"
A.txt B.txt C.txt

# This cannot be evaluated, so it returns whatever is between quotes, literally.
[user@work test]$ echo='echo *.txt'; echo '$($echo)'
$($echo)

คุณสามารถใช้เครื่องหมายคำพูดเดี่ยวภายในเครื่องหมายคำพูดคู่และคุณสามารถใช้เครื่องหมายคำพูดคู่ภายในเครื่องหมายคำพูดคู่ แต่เครื่องหมายอัญประกาศคู่ภายในเครื่องหมายคำพูดเดี่ยวไม่ควรทำ (โดยไม่ต้องหลบหนีพวกเขา)จะไม่ถูกประเมิน ไม่ควรทำเครื่องหมายคำพูดเดี่ยวในเครื่องหมายคำพูดเดี่ยว (โดยไม่ต้องหลีกหนี)

คุณจะต้องเข้าใจราคาอย่างถี่ถ้วนเพื่อใช้ Bash อย่างมีประสิทธิภาพ สำคัญมาก!

ตามกฎทั่วไปฉันไม่ใช้เครื่องหมายอัญประกาศถ้าฉันต้องการให้ Bash ขยายบางสิ่งออกเป็นองค์ประกอบ (เช่นอาร์เรย์) ฉันใช้เครื่องหมายอัญประกาศเดี่ยวสำหรับสตริงตัวอักษรที่ไม่ได้รับการแก้ไข ที่น่าจะส่งคืนสตริงประเภทใดก็ได้ นี่คือเพื่อให้แน่ใจว่าช่องว่างและอักขระพิเศษจะถูกเก็บไว้


คุณจะใช้เครื่องหมายคำพูดคู่ภายในเครื่องหมายคำพูดคู่ได้อย่างไร นั่นคือการพิมพ์ผิดหรือเปล่า? และทำไมฉันควรหลีกเลี่ยงเครื่องหมายคำพูดคู่ภายในเครื่องหมายคำพูดเดี่ยวแทน? ฉันเดาว่าคุณประสมประโยคใช่มั้ย
ผู้บัญชาการไบต์

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