Bagaimana saya bisa menulis skrip shell yang akan melakukan kecocokan substring case-output output perintah?
shell-script
shell
string
Miguel Roque
sumber
sumber
grep -i
mungkin?bash
, yang merupakan superset dari standar unixsh
. Anda mungkin mulai dengan melihat salah satu dari ini: | 1 | | 2 | - hanya untuk memahami konteks sebenarnya.Jawaban:
Pertama, inilah contoh skrip sederhana yang tidak mengabaikan kasus:
Coba ubah string halo di sebelah kanan, dan seharusnya tidak lagi bergema
it works
. Coba gantiecho hello
dengan perintah yang Anda pilih. Jika Anda ingin mengabaikan case, dan tidak ada string yang berisi satu baris pun, maka Anda bisa menggunakan grep:Kuncinya di sini adalah bahwa Anda mengirim output perintah
grep
. Theif
pernyataan menguji status keluar dari perintah paling kanan dalam pipa - dalam hal ini grep. Grep keluar dengan sukses jika dan hanya jika ia menemukan kecocokan.The
-i
pilihan untuk grep mengatakan untuk mengabaikan kasus.The
-q
pilihan mengatakan untuk tidak memancarkan dan keluar setelah pertandingan pertama.The
-F
pilihan kata untuk mengobati argumen sebagai string daripada ekspresi reguler.Perhatikan bahwa contoh pertama menggunakan yang memungkinkan perbandingan langsung dan berbagai operator yang bermanfaat. Bentuk kedua hanya mengeksekusi perintah dan menguji status keluar mereka.
[ expression ]
sumber
==
bukan POSIX.sh
tidakbash
pada semua sistem berbasis Linux.==
tidak didukung olehash
(yang menjadi dasarsh
dari banyaknya BSD dan turunan Debian setidaknya), atauposh
, dan kebutuhan dikutip dalamzsh
. Tidak ada gunanya menggandakan=
.[
adalah perintah untuk pengujian. Tidak perlu membingungkan antara tugas dan perbandingan di sini. Itu berbeda dalam(( a == b ))
vs(( a = b))
. Menggunakan==
skrip yang dimulai dengan#! /bin/sh
salah. Jika Anda menganggapksh
ataubash
sintaksis, perbarui#!
sesuai.Anda dapat melakukan pencocokan substrat case-insensitive dengan asli dalam
bash
menggunakan operator regex=~
jika Anda mengaturnocasematch
opsi shell. Sebagai contohsumber
[[ XYZ == xyz ]] && echo "match"
=>match
Untuk pencarian string case-sensitive dari nilai variabel
needle
dalam nilai variabelhaystack
:Untuk pencarian string yang tidak memiliki case-case, konversikan keduanya menjadi case yang sama.
Perhatikan bahwa
tr
dalam coreutils GNU tidak mendukung lokal multibyte (misalnya UTF-8). Untuk bekerja dengan multibyte lokal, gunakan awk sebagai gantinya. Jika Anda akan menggunakan awk, Anda dapat membuatnya melakukan perbandingan string dan bukan hanya konversi.The
tr
dari BusyBox tidak mendukung sintaks; Anda bisa menggunakannya . BusyBox tidak mendukung lokal non-ASCII.[:CLASS:]
tr a-z A-Z
Di bash (tetapi bukan sh), versi 4.0+, ada sintaks bawaan untuk konversi kasus, dan sintaksis lebih sederhana untuk pencocokan string.
sumber
printf | tr
membuat kepala saya berputar. Jika memungkinkan, pertahankan perintah Anda seminimal mungkin ... dengan variabel v, Anda dapat menggunakan hal yang samav=$(tr '[:lower:]' '[:upper:]' <<<$v)
. Bagi mereka yang belum pernah melihatnya sebelumnya,<<<
ini pada dasarnya adalah "variabel di sini" seperti penggunaan<<EOF
adalah untuk dokumen di sini. Janganprintf
atauecho
kecuali Anda benar-benar harus melakukannya.<<<
operator: ksh, bash, zsh, tetapi tidak sh polos. Dan itu cukup dekat dengan pemipaanprintf
dalam hal cara kerjanya: ada jumlah panggilan yang sama kefork
danexecve
(dengan asumsi ituprintf
adalah built-in, yang merupakan kasus pada shell paling umum); perbedaannya adalah yang<<<
membuat file sementara daripada menggunakan pipa.<<<
nyaman untuk mengetik tetapi bukan peningkatan kinerja.