греп на змінну


58

Скажімо, у мене є змінна

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

тепер я хочу прослідкувати, скільки разів у реченні трапляється виділення.

grep -ci "select" $line

Я спробував це, але не вийшло. Я також спробував

grep -ci "select" "$line"

Це все ще не працює. Я отримую таку помилку.

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

1
Потрібно використовувати херестінг ...<<<"$line" . Команда grepочікує файлу замість цього
Валентин Байрамі

Відповіді:


85

Чи були grepпрочитати на стандартне введення. Там ви йдете, використовуючи трубу ...

$ echo "$line" | grep select

... або рядок тут ...

$ grep select <<< "$line"

Також, можливо, ви захочете замінити пробіли на нові рядки перед прив’язкою:

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

... або ви можете попросити grepроздрукувати матч лише:

$ echo "$line" | grep -o select

Це дозволить вам позбутися від решти рядка, коли є матч.

Редагувати: На жаль, читайте занадто швидко, дякую Марко . Для того, щоб порахувати випадки, просто перекажіть будь-яку з цих wc(1);)

Ще одна редакція, зроблена після коментаря lzkata з цитуванням $lineпри використанні echo.


3
Оскільки ОП хоче підрахувати кількість вхідних рядків, ви можете додати wcзавдання для виконання завдання:grep -o <string> <<< "$variable" | wc -l
Марко,

2
Використовуйте echo "$line"для збереження існуючих нових рядків замість того, щоб створювати їх за допомогоюtr
Izkata

Яка наявність тут String? Це вимагає Bash або іншої оболонки?

Згідно з Вікіпедією , тут є рядки в bash, ksh та zsh (але я припускаю, що можуть бути й інші).
Джон У. Сміт

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

Вам не потрібно закликати grepдо такої простої речі.

Або як функція:

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

На це потрібно 2 або 3 аргументи. Забезпечення будь-яких більше, що призведе до перекручування її результатів. Ви можете використовувати його так:

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

... яка друкує кількість тієї, що зустрічається .в систему, ...якщо це відбувається , по крайней мере в 2 рази. Подобається це:

count: 3

Якщо $_occurвін порожній або unsetколи він викликається, він не вплине на змінні оболонки і return1, якщо "$2"виникає "$1"менше, ніж у кілька "$3"разів. Або, якщо його викликають лише два аргументи, це буде return1, лише якщо "$2"його немає "$1". В іншому випадку вона повертає 0.

Отже, у найпростішому вигляді ви можете:

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

... які друкує ...

shite

... але ...

occur . . && echo yay || echo shite

... надрукує ...

yay

Ви також можете написати це трохи інакше і пропустити цитати $2в як (*"$2"*)і в "${1#*"$2"}"заяві. Якщо ви це зробите, то ви можете використовувати кулі-оболонки для матчів, як sh[io]teдля тесту на відповідність.


1
+1: Справді, швидше. Працює в bashі dash/ sh(і, мабуть, у кількох інших).
Джон У. Сміт

@JohnWHSmith - редагування краще, але все-таки так само портативно.
mikeserv
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.