Saya memiliki file yang berisi nama direktori:
my_list.txt
:
/tmp
/var/tmp
Saya ingin memeriksa di Bash sebelum saya akan menambahkan nama direktori jika nama itu sudah ada di file.
Saya memiliki file yang berisi nama direktori:
my_list.txt
:
/tmp
/var/tmp
Saya ingin memeriksa di Bash sebelum saya akan menambahkan nama direktori jika nama itu sudah ada di file.
Jawaban:
grep -Fxq "$FILENAME" my_list.txt
Status keluar adalah 0 (benar) jika nama itu ditemukan, 1 (salah) jika tidak, jadi:
if grep -Fxq "$FILENAME" my_list.txt
then
# code if found
else
# code if not found
fi
Berikut adalah bagian yang relevan dari halaman manual untukgrep
:
grep [options] PATTERN [FILE...]
-F
,--fixed-strings
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
-s
atau--no-messages
.
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:
Biasanya, status keluar adalah 0 jika baris yang dipilih ditemukan dan 1 sebaliknya. Tetapi status keluar adalah 2 jika kesalahan terjadi, kecuali jika opsi
-q
atau--quiet
atau--silent
digunakan dan baris yang dipilih ditemukan. Catatan, bagaimanapun, bahwa POSIX hanya mandat, untuk program-program sepertigrep
,cmp
, dandiff
, 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 grep
mungkin dicetak akan berakhir di konsol seperti yang Anda inginkan.
Untuk menangani tiga kasus, kita dapat menggunakan case
pernyataan:
case `grep -Fx "$FILENAME" "$LIST" >/dev/null; echo $?` in
0)
# code if found
;;
1)
# code if not found
;;
*)
# code if an error occurred
;;
esac
$?
. Anda juga dapat menggunakan perintah grep di samping if
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:
grep -Fxq "$FILENAME" my_list.txt
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:
-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.)
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 content
then
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.
Cara yang lebih sederhana:
if grep "$filename" my_list.txt > /dev/null
then
... found
else
... not found
fi
Tip: kirim ke /dev/null
jika Anda ingin status keluar perintah, tetapi bukan keluaran.
-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:
isInFile=$(cat file.txt | grep -c "string")
if [ $isInFile -eq 0 ]; then
#string not contained in file
else
#string is in file at least once
fi
grep -c akan mengembalikan hitungan berapa kali string muncul dalam file.
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
grep -q
dan memanggil grep langsung if
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).
grep -E "(string)" /path/to/file || echo "no match found"
Opsi -E membuat grep menggunakan ekspresi reguler
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
Semoga ini bisa membantu seseorang
Solusi tanpa grep, bekerja untuk saya:
MY_LIST=$( cat /path/to/my_list.txt )
if [[ "${MY_LIST}" == *"${NEW_DIRECTORY_NAME}"* ]]; then
echo "It's there!"
else
echo "its not there"
fi
berdasarkan pada: https://stackoverflow.com/a/229606/3306354
grep -q
dijelaskan dalam jawaban yang diterima adalah pendekatan yang paling efisien.
grep -Fxq "String to be found" | ls -a