Menafsirkan POLA sebagai daftar string tetap, dipisahkan oleh baris baru, yang mana saja yang harus dicocokkan.
-x, --line-regexp
Pilih hanya yang cocok persis dengan seluruh baris.
-q, --quiet,--silent
Diam; jangan menulis apa pun ke output standar. Segera keluar dengan status nol jika ada kecocokan yang ditemukan, bahkan jika kesalahan terdeteksi. Lihat juga opsi -satau --no-messages.
Menangani kesalahan
Sebagaimana ditunjukkan dalam komentar, pendekatan di atas diam-diam memperlakukan kasus kesalahan seolah-olah string ditemukan. Jika Anda ingin menangani kesalahan dengan cara yang berbeda, Anda harus menghilangkan -qopsi, dan mendeteksi kesalahan berdasarkan status keluar:
Biasanya, status keluar adalah 0 jika baris yang dipilih ditemukan dan 1 sebaliknya. Tetapi status keluar adalah 2 jika kesalahan terjadi, kecuali jika opsi -qatau --quietatau --silentdigunakan dan baris yang dipilih ditemukan. Catatan, bagaimanapun, bahwa POSIX hanya mandat, untuk program-program seperti grep, cmp, dan diff, bahwa status exit terjadi error lebih besar dari 1; Oleh karena itu disarankan, demi portabilitas, untuk menggunakan logika yang menguji kondisi umum ini alih-alih kesetaraan ketat dengan 2.
Untuk menekan output normal grep, Anda dapat mengarahkan ulang ke /dev/null. Perhatikan bahwa kesalahan standar tetap tidak terarah, sehingga pesan kesalahan yang grepmungkin dicetak akan berakhir di konsol seperti yang Anda inginkan.
Untuk menangani tiga kasus, kita dapat menggunakan casepernyataan:
case`grep -Fx "$FILENAME" "$LIST" >/dev/null; echo $?`in0)# code if found;;1)# code if not found;;*)# code if an error occurred;;esac
Jika saya menjalankan perintah ini dari skrip bash bagaimana cara menangkap 0 atau 1 menjadi variabel?
Toren
6
@ Toren Sebagian besar status keluar terakhir dapat diakses menggunakan $?. Anda juga dapat menggunakan perintah grep di samping ifpernyataan (seperti yang ditunjukkan pada jawaban yang diperbarui).
Shawn Chin
5
Anda dapat menggunakan grep -Fqx "$FILENAME"dan Anda tidak perlu khawatir tentang karakter regex dalam konten variabel dan Anda tidak harus menggunakannya dalam string pencarian.
Dijeda sampai pemberitahuan lebih lanjut.
4
Beberapa catatan untuk orang-orang yang mencari jawaban ini: 1) Dalam bash, 0 selalu benar dan yang lainnya selalu salah 2) Hanya menggunakan flag -x jika Anda ingin seluruh baris cocok persis. Jika Anda hanya ingin mengetahui apakah string Anda ada di file sama sekali, biarkan saja. Jika Anda ingin mengetahui apakah string Anda benar-benar ada tetapi tanpa mencocokkan seluruh baris (misalnya, sebagai keseluruhan kata), gunakan -w.
Schmick
1
Saya tidak mengerti -q / --silentapakah ini dibutuhkan? Itu salah mengatakan "semua baik" untuk bash bahkan jika kesalahan terjadi. Jika saya mendapatkannya dengan benar. Tampaknya konsep yang cacat untuk kasus ini.
redanimalwar
90
Mengenai solusi berikut:
grep -Fxq"$FILENAME" my_list.txt
Jika Anda bertanya-tanya (seperti yang saya lakukan) apa -Fxqartinya dalam bahasa Inggris yang sederhana:
F: Mempengaruhi bagaimana POLA ditafsirkan (string tetap bukan suatu regex)
x: Cocokkan seluruh baris
q: Shhhhh ... pencetakan minimal
Dari file man:
-F,--fixed-strings
Interpret PATTERN as a list of fixed strings, separated by newlines, any of which is to be matched.(-F is specified by POSIX.)-x,--line-regexp
Select only those matches that exactly match the whole line.(-x is specified by POSIX.)-q,--quiet,--silent
Quiet;do not write anything to standard output.Exit immediately with zero status if any match is
found, even if an error was detected.Also see the -s or --no-messages option.(-q is specified by
POSIX.)
-F tidak mempengaruhi pemrosesan file, itu mempengaruhi bagaimana POLA ditafsirkan. Biasanya, POLA ditafsirkan sebagai regex, tetapi dengan -F akan ditafsirkan sebagai string tetap.
Adam S
41
Tiga metode dalam pikiran saya:
1) Tes singkat untuk nama di jalur (Saya tidak yakin ini mungkin kasus Anda)
ls -a "path"| grep "name"
2) Tes singkat untuk string dalam file
grep -R "string""filepath"
3) Skrip bash yang lebih panjang menggunakan regex:
#!/bin/bash
declare file="content.txt"
declare regex="\s+string\s+"
declare file_content=$( cat "${file}")if[[" $file_content "=~ $regex ]]# please note the space before and after the file contentthen
echo "found"else
echo "not found"fi
exit
Ini harus lebih cepat jika Anda harus menguji beberapa string pada konten file menggunakan loop misalnya mengubah regex di setiap siklus.
Anda tidak perlu menguji keluaran grep, Anda cukup menggunakan grep -qdan memanggil grep langsung ifseperti yang dilakukan Thomas dalam jawabannya. Selain itu, pertanyaannya tidak termasuk memeriksa apakah direktori tersebut ada sebelum menambahkannya ke daftar (setelah semua, itu bisa menjadi daftar direktori yang dihapus).
sorpigal
Saya menghapus contoh skrip, itu tidak menambahkan apa pun ke jawaban yang diberikan oleh Thomas.
lecodesportif
3
Jika Anda hanya ingin memeriksa keberadaan satu baris, Anda tidak perlu membuat file. Misalnya,
if grep -xq "LINE_TO_BE_MATCHED" FILE_TO_LOOK_IN ;then# code for if it existselse# code for if it does not existfi
Solusi @ Thomas tidak bekerja untuk saya untuk beberapa alasan tetapi saya memiliki string yang lebih panjang dengan karakter khusus dan spasi putih jadi saya hanya mengubah parameter seperti ini:
if grep -Fxq'string you want to find'"/path/to/file";then
echo "Found"else
echo "Not found"fi
Jawaban:
Status keluar adalah 0 (benar) jika nama itu ditemukan, 1 (salah) jika tidak, jadi:
Penjelasan
Berikut adalah bagian yang relevan dari halaman manual untuk
grep
:Menangani kesalahan
Sebagaimana ditunjukkan dalam komentar, pendekatan di atas diam-diam memperlakukan kasus kesalahan seolah-olah string ditemukan. Jika Anda ingin menangani kesalahan dengan cara yang berbeda, Anda harus menghilangkan
-q
opsi, dan mendeteksi kesalahan berdasarkan status keluar:Untuk menekan output normal
grep
, Anda dapat mengarahkan ulang ke/dev/null
. Perhatikan bahwa kesalahan standar tetap tidak terarah, sehingga pesan kesalahan yanggrep
mungkin dicetak akan berakhir di konsol seperti yang Anda inginkan.Untuk menangani tiga kasus, kita dapat menggunakan
case
pernyataan:sumber
$?
. Anda juga dapat menggunakan perintah grep di sampingif
pernyataan (seperti yang ditunjukkan pada jawaban yang diperbarui).grep -Fqx "$FILENAME"
dan Anda tidak perlu khawatir tentang karakter regex dalam konten variabel dan Anda tidak harus menggunakannya dalam string pencarian.-q / --silent
apakah ini dibutuhkan? Itu salah mengatakan "semua baik" untuk bash bahkan jika kesalahan terjadi. Jika saya mendapatkannya dengan benar. Tampaknya konsep yang cacat untuk kasus ini.Mengenai solusi berikut:
Jika Anda bertanya-tanya (seperti yang saya lakukan) apa
-Fxq
artinya dalam bahasa Inggris yang sederhana:F
: Mempengaruhi bagaimana POLA ditafsirkan (string tetap bukan suatu regex)x
: Cocokkan seluruh barisq
: Shhhhh ... pencetakan minimalDari file man:
sumber
Tiga metode dalam pikiran saya:
1) Tes singkat untuk nama di jalur (Saya tidak yakin ini mungkin kasus Anda)
2) Tes singkat untuk string dalam file
3) Skrip bash yang lebih panjang menggunakan regex:
Ini harus lebih cepat jika Anda harus menguji beberapa string pada konten file menggunakan loop misalnya mengubah regex di setiap siklus.
sumber
Cara yang lebih sederhana:
Tip: kirim ke
/dev/null
jika Anda ingin status keluar perintah, tetapi bukan keluaran.sumber
-q
yang sama seperti--quiet
:)-q
juga jawaban terbaik di sini, dan di tempat keempat. tidak ada keadilan di dunia ini.Cara termudah dan paling sederhana adalah:
grep -c akan mengembalikan hitungan berapa kali string muncul dalam file.
sumber
Jika saya memahami pertanyaan Anda dengan benar, ini harus melakukan apa yang Anda butuhkan.
Dalam satu baris :
check="/tmp/newdirectory"; [[ -n $(grep "^$check\$" my_list.txt) ]] && echo "dir already listed" || echo "$check" >> my_list.txt
sumber
grep -q
dan memanggil grep langsungif
seperti yang dilakukan Thomas dalam jawabannya. Selain itu, pertanyaannya tidak termasuk memeriksa apakah direktori tersebut ada sebelum menambahkannya ke daftar (setelah semua, itu bisa menjadi daftar direktori yang dihapus).Jika Anda hanya ingin memeriksa keberadaan satu baris, Anda tidak perlu membuat file. Misalnya,
sumber
Versi saya menggunakan fgrep
sumber
-c
opsi difgrep --help
Opsi -E membuat grep menggunakan ekspresi reguler
sumber
Solusi @ Thomas tidak bekerja untuk saya untuk beberapa alasan tetapi saya memiliki string yang lebih panjang dengan karakter khusus dan spasi putih jadi saya hanya mengubah parameter seperti ini:
Semoga ini bisa membantu seseorang
sumber
Solusi tanpa grep, bekerja untuk saya:
berdasarkan pada: https://stackoverflow.com/a/229606/3306354
sumber
grep -q
dijelaskan dalam jawaban yang diterima adalah pendekatan yang paling efisien.sumber
sumber