Apa perbedaan antara file grep apple dan file grep "apple"?

22

Apa perbedaan antara grep apple filedan grep "apple" file? Apa yang dilakukan dengan menempatkan tanda kutip? Keduanya tampak berfungsi dan melakukan hal yang sama persis (menampilkan garis yang sama).

John Stacen
sumber

Jawaban:

45

Tanda kutip memiliki efek pada karakter apa yang Anda anggap istimewa oleh shell dan memiliki makna sintaksis. Dalam contoh Anda ini tidak membuat perbedaan karena appletidak mengandung karakter seperti itu.

Tetapi perhatikan contoh lain: grep apple tree fileakan mencari kata appledalam file treedan file, sedangkan grep "apple tree" fileakan mencari kata apple treedalam file file. Tanda kutip memberi tahu bash, bahwa ruang kata di "apple tree"tidak memulai parameter baru tetapi harus menjadi bagian dari parameter saat ini. grep apple\ tree fileakan menghasilkan hasil yang sama, karena \memberitahu bash untuk mengabaikan makna khusus karakter berikut dan memperlakukannya secara harfiah.

David Foerster
sumber
2
Ini juga terlihat dengan wildcard. Jika Anda melakukannya grep a*b equations.txtmaka ia akan mencari a*b, kecuali ada file di direktori saat ini dimulai dengan, dan berakhir dengan b, dalam hal ini (karena (ba) sh akan memperluas nama file pada baris perintah) grep akan dipanggil dengan melengkapi parameter yang berbeda, menghasilkan hasil yang berbeda. Ini biasanya lebih merupakan masalah dengan find, karena perintah seperti find . -name *.txtakan menghasilkan perilaku yang tidak terduga, jika ada file txt di direktori saat ini. Lebih baik menggunakan kutipan dalam kasus ini.
SztupY
4
Poin penting lainnya adalah perbedaan antara tanda kutip ganda ( ") dan tanda kutip tunggal ( '). Kutipan tunggal mencegah interpretasi karakter tertentu seperti $, sedangkan tanda kutip ganda memungkinkan interpretasi. Misalnya grep '${USER}'akan mencari teks ${USER}, sedangkan grep "${USER}"akan mencari teks yang USERberisi variabel (misalnya johnstacen).
Paddy Landau
23

Kutipan ganda memungkinkan evaluasi, kutipan tunggal mencegah evaluasi, tidak ada tanda kutip memungkinkan ekspansi wildcard, ketika digunakan pada baris perintah. Sebagai contoh yang dibuat-buat:

[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

Memahami cara kerja kutipan sangat penting untuk memahami Bash. Sebagai contoh:

# 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)

Anda dapat menggunakan tanda kutip tunggal untuk memberikan perintah melalui variabel. Kutipan tunggal akan mencegah evaluasi. Kutipan ganda akan dievaluasi.

# 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)

Anda dapat menggunakan tanda kutip tunggal di dalam tanda kutip ganda dan Anda dapat menggunakan tanda kutip ganda di dalam tanda kutip ganda, tetapi tanda kutip ganda di dalam tanda kutip tunggal tidak boleh dilakukan (tanpa melarikan diri) tidak akan dievaluasi, mereka akan ditafsirkan secara harfiah. Kutipan tunggal dalam tanda kutip tunggal tidak boleh dilakukan (tanpa melarikan diri).

Anda harus mendapatkan pemahaman menyeluruh tentang kutipan untuk menggunakan Bash secara efektif. Sangat penting!

Sebagai aturan umum, saya tidak menggunakan tanda kutip jika saya ingin Bash memperluas sesuatu menjadi elemen (seperti array), saya menggunakan tanda kutip tunggal untuk string literal yang tidak dapat diubah, dan saya menggunakan liberal tanda kutip ganda untuk variabel yang cenderung mengembalikan semua jenis string. Ini untuk memastikan bahwa spasi dan karakter khusus akan dipertahankan.

AsymLabs
sumber
Bagaimana Anda menggunakan tanda kutip ganda di dalam tanda kutip ganda ??? Apakah itu salah cetak? Dan mengapa saya harus menghindari tanda kutip ganda di dalam tanda kutip tunggal? Saya kira Anda mencampuradukkan kalimat mungkin?
Byte Commander
@ByteCommander Ya konsep tanda kutip ganda ditempatkan di dalam tanda kutip ganda digunakan cukup umum - lihat posting ini untuk contoh kerja yang menonjol. Ini biasanya dilakukan untuk melindungi string yang berisi spasi, sering kali berkenaan dengan string path. Kutipan ganda dapat digunakan dalam tanda kutip tunggal dengan atau tanpa melarikan diri, tetapi mereka akan ditafsirkan secara harfiah, yaitu mereka tidak akan mengarah pada evaluasi. Saya akan menjelaskan poin ini di posting.
AsymLabs