Saya akan mulai dengan mengatakan bahwa saya pikir masalah ini sedikit tidak bersalah daripada kedengarannya.
Yang perlu saya lakukan: periksa folder dalam variabel lingkungan PATH. Itu bisa di awal atau di suatu tempat setelah. Saya hanya perlu memverifikasi bahwa folder itu ada di sana.
Contoh masalah saya - mari kita gunakan /opt/gnome
.
SKENARIO 1: folder bukan di awal PATH
# echo "$PATH"
/sbin:/usr/sbin:/opt/gnome:/var/opt/gnome
# echo "$PATH" | grep ":/opt/gnome"
/sbin:/usr/sbin:/opt/gnome:/var/opt/gnome
Perhatikan bahwa grep harus cukup spesifik sehingga tidak menangkap /var/opt/gnome
. Karena itu usus besar.
SKENARIO 2: folder berada di awal PATH.
# echo "$PATH"
/opt/gnome:/sbin:/usr/sbin:/var/opt/gnome
# echo "$PATH" | grep "^/opt/gnome"
/opt/gnome:/sbin:/usr/sbin:/var/opt/gnome
Ini masalah saya - saya perlu mencari titik dua atau titik awal dengan folder ini. Apa yang ingin saya lakukan adalah salah satu dari dua ungkapan braket ini:
# echo $PATH | grep "[^:]/opt/gnome"
# echo $PATH | grep "[:^]/opt/gnome"
TAPI [^
dan [:
punya artinya sendiri. Karena itu, kedua perintah di atas tidak berfungsi.
Apakah ada cara saya bisa memahami dua skenario ini dalam satu perintah?
sumber
/opt/gnome:
atau/opt/gnome$
, Anda akan menemukan/opt/gnome-foo
atau/opt/gnome/bar
.grep '^\(any number of other matches:*:\)*my match\(:.*\)*$'
Jawaban:
Jika Anda memeriksa konten
PATH
variabel lingkungan, bukan mencari sesuatu dalam file, maka itugrep
adalah alat yang salah. Lebih mudah (dan lebih cepat dan bisa dibilang lebih mudah dibaca) untuk melakukannya di shell.Dalam bash, ksh dan zsh:
Mudah dibawa:
Perhatikan penggunaan
:$PATH:
daripada$PATH
; dengan cara ini, komponen selalu dikelilingi oleh titik dua dalam string pencarian bahkan jika itu pada awal atau akhir$PATH
.Jika Anda mencari melalui satu baris file, maka Anda dapat menggunakan regexp tambahan (yaitu membutuhkan
grep -E
)(^|:)/opt/gnome($|:)
untuk mencocokkan/opt/gnome
tetapi hanya jika itu pada awal baris atau mengikuti titik dua, dan hanya jika itu pada akhir garis atau diikuti oleh titik dua.sumber
Anda dapat menggunakan ekspresi reguler yang diperluas dengan hanya menggunakan
grep -E
Anda harus mencocokkan awal dan akhir jalan yang Anda coba temukan jika Anda ingin menghindari kesalahan positif.
Cocok dengan instance di awal:
Juga cocok dengan instance di tengah:
Menghindari kesalahan positif:
Tidak ada yang cocok di sana.
Kompak dan elegan. Diuji pada Debian 7.
sumber
egrep
adalah penggunaan yang dihentikangrep -E
(sumber:man grep
)-w
pilihan memiliki beberapa masalah. Hanya digit, huruf, dan garis bawah yang dianggap "kata". Jadi beberapa karakter yang tidak biasa tetapi mungkin akan membuatnya gagal. Contohecho '/sbin:/usr/sbin:/var-/opt/gnome' | grep -w "/opt/gnome"
danecho '/sbin:/usr/sbin:/var./opt/gnome' | grep -w "/opt/gnome"
. Itu memberikan hasil yang salah./opt/gnome/somethingelse
.echo "/home/bob/opt/gnome:/opt/gnome/somethingelse:/opt/gnome-beta" | grep -E "(:|^)/opt/gnome(:|$)"
. Mengedit jawaban.Jika Anda tidak menikah
grep
, Anda dapat menggunakanawk
dan memisahkan catatan:
sumber
Anda juga bisa menggunakannya
echo "$PATH" | tr ':' '\n' | grep -x "/opt/gnome"
yang membagi variabel path menjadi baris terpisah (satu per path), sehingga
grep -x
dapat mencari hasil yang tepat. Ini tentu saja memiliki kekurangan yang membutuhkan proses tambahantr
. Dan itu tidak akan berfungsi ketika nama folder diPATH
mengandung karakter baris baru.sumber
Saya tidak tahu apakah cukup untuk menjawab tetapi
akan memuaskan kebutuhan anda.
tapi
sumber
/
bukan bagian dari kata tetapir
adalah./opt/gnome-beta
,,/home/bob/opt/gnome
...grep -w /usr/local -o <<< /usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/usr/games:/usr/local/games
/usr/local /usr/local /usr/local
Untuk pilih
/opt/gnome
dikelilingi oleh karakter non-kata (baris baru,:
,/
, dll) mencoba yang satu ini:sumber
Anda dapat melakukan ini dengan andal dan dengan sedikit usaha di
grep
. Anda dapat memanfaatkan ekstensi yang tersedia secara luas dan di antaranya banyak solusi telah ditawarkan, tetapi bahkan dengan regex dasar hal itu mudah dilakukan, meskipun mungkin tidak secara intuitif jadi pada pandangan pertama.Dengan regex dasar - dan sebagainya
grep
- Anda selalu memiliki dua jangkar yang dapat diandalkan - kepala dan ekor garis. Anda dapat mengaitkan kecocokan dengan keduanya terlepas dari lokasinya di baris seperti:grep
akan cocok dari kepala baris sebanyak kemunculan\(grouped\)
subekspresi yang harus dihadapi di samping pembatas Anda kemudian pertandingan eksplisit Anda, dan dari ekor pertandingan Anda ke ekor garis dengan cara yang sama. Jika kecocokan eksplisit Anda tidak dicocokkan secara eksplisit itu akan gagal dan tidak mencetak apa pun.Dan itulah yang mungkin Anda lakukan, misalnya:
Lihat diri mu sendiri:
KELUARAN
sumber
Anda telah memperhatikan kasing tepi ... Anda bisa menghindarinya dengan memaksa penampakan a: di awal baris:
atau jika jalurnya tepat tambahkan juga satu di akhir untuk memastikan itu dibatasi:
sumber