grep pada sebuah variabel


58

Katakanlah saya punya variabel

line="This is where we select from a table."

sekarang saya ingin memahami berapa kali pemilihan terjadi pada kalimat.

grep -ci "select" $line

Saya mencoba itu, tetapi tidak berhasil. Saya juga mencoba

grep -ci "select" "$line"

Itu masih tidak berhasil. Saya mendapatkan kesalahan berikut.

grep: This is where we select from a table.: No such file or directory

1
Anda perlu menggunakan herestring ...<<<"$line" . Perintahnya grepmengharapkan file sebagai gantinya
Valentin Bajrami

Jawaban:


85

Telah grepmembaca input standarnya. Ini dia, menggunakan pipa ...

$ echo "$line" | grep select

... atau string di sini ...

$ grep select <<< "$line"

Selain itu, Anda mungkin ingin mengganti spasi dengan baris baru sebelum menangkap:

$ echo "$line" | tr ' ' '\n' | grep select

... atau Anda bisa meminta grepuntuk mencetak pertandingan saja:

$ echo "$line" | grep -o select

Ini akan memungkinkan Anda untuk menyingkirkan sisa baris ketika ada kecocokan.

Sunting: Ups, baca sedikit terlalu cepat, terima kasih Marco . Untuk menghitung kejadian, kirimkan saja semua ini ke wc(1);)

Suntingan lain dilakukan setelah komentar lzkata , mengutip $linesaat menggunakan echo.


3
Karena OP ingin menghitung jumlah kemunculan string, Anda dapat menambahkan wcuntuk menyelesaikan tugas:grep -o <string> <<< "$variable" | wc -l
Marco

2
Gunakan echo "$line"untuk melestarikan baris baru yang sudah ada alih-alih membuat yang baru dengantr
Izkata

Apa ketersediaan String Di Sini? Apakah itu membutuhkan Bash atau shell lain?

Menurut Wikipedia , di sini string tersedia dalam bash, ksh, dan zsh (tapi saya berasumsi mungkin ada yang lain).
John WH Smith

7
test=$line i=0
while case "$test" in (*select*)
test=${test#*select};;(*) ! :;;
esac; do i=$(($i+1)); done

Anda tidak perlu menelepon grepuntuk hal yang sangat sederhana.

Atau sebagai fungsi:

occur() while case "$1" in (*"$2"*) set -- \
        "${1#*"$2"}" "$2" "${3:-0}" "$((${4:-0}+1))";;
        (*) return "$((${4:-0}<${3:-1}))";;esac
        do : "${_occur:+$((_occur=$4))}";done

Dibutuhkan 2 atau 3 argumen. Memberikan lebih dari itu akan membuat hasilnya miring. Anda bisa menggunakannya seperti:

_occur=0; occur ... . 2 && echo "count: $_occur"

... yang mencetak hitungan kemunculan .in ...jika itu terjadi setidaknya 2 kali. Seperti ini:

count: 3

Jika $_occurkosong atau unsetketika dipanggil maka itu tidak akan mempengaruhi variabel shell sama sekali dan return1 jika "$2"terjadi dalam waktu yang "$1"lebih sedikit "$3". Atau, jika dipanggil dengan hanya dua arg, itu returnhanya akan 1 jika "$2"tidak ada "$1". Jika tidak mengembalikan 0.

Jadi, dalam bentuknya yang paling sederhana, Anda dapat melakukan:

occur '' . && echo yay || echo shite

... yang mencetak ...

shite

...tapi...

occur . . && echo yay || echo shite

... akan mencetak ...

yay

Anda mungkin juga menulisnya sedikit berbeda dan menghilangkan tanda kutip $2di kedua bagian (*"$2"*)dan "${1#*"$2"}"pernyataan. Jika Anda melakukannya, Anda dapat menggunakan gumpalan shell untuk pertandingan seperti sh[io]teuntuk tes pertandingan.


1
+1: Lebih cepat, memang. Bekerja di bashdan dash/ sh(dan mungkin beberapa lainnya).
John WH Smith

@JohnWHSmith - hasil edit lebih baik, tetapi tetap portabel.
mikeserv
Dengan menggunakan situs kami, Anda mengakui telah membaca dan memahami Kebijakan Cookie dan Kebijakan Privasi kami.
Licensed under cc by-sa 3.0 with attribution required.