Как использовать awk, чтобы найти символ в строке в bash - PullRequest
0 голосов
/ 22 апреля 2020

У меня есть переменная char с именем sign и заданная строка sub. Мне нужно выяснить, сколько раз этот sign появляется в sub и не может использовать grep.

Например:

sign = c

sub = mechanic cup cat

echo "$sub" | awk <code i am asking for> | wc -l

И вывод должен быть 4 потому что c появляется 4 раза. Что должно быть внутри <>?

Ответы [ 2 ]

2 голосов
/ 22 апреля 2020
sign=c
sub='mechanic cup cat'

echo "$sub" |
  awk -v sign="$sign" -F '' '{for (i=1;i<=NF;i++){if ($i==sign) cnt++}} END{print cnt}'

Редактировать:

Изменения требований в комментарии :

  1. Проверить длину sign равно 1 (нет = присутствует). Если true, измените sign и sub на строчные буквы, чтобы игнорировать регистр.
  2. Используйте ${sign:0:1}, чтобы передать только первый символ awk.

sign=c
sub='mechanic Cup cat'

if [ "${#sign}" -eq 1 ]; then
  sign=${sign,,}
  sub=${sub,,}
fi

echo "$sub" |
  awk -v sign="${sign:0:1}" -F '' '{for (i=1;i<=NF;i++){if ($i==sign) cnt++}} END{print cnt}'
0 голосов
/ 22 апреля 2020

Комбинация комментария Квазимодо и примера Фредди в нижнем регистре:

$ sign=c
$ sub='mechanic Cup cat'

A tr + wc решение, если ${sign} - один символ.

Подсчитайте, сколько раз ${sign} отображается в ${sub}, игнорируя регистр:

$ tr -cd [${sign,,}] <<< ${sub,,} | wc -c
4

Где:

  • ${sign,,} & {sub,,} - преобразовать во все строчные буквы
  • tr -cd [...] - найти все символы, перечисленные в скобках ([]), -d говорит об удалении / удалении указанных символов, в то время как -c говорит о том, чтобы взять дополнение (ie, удалить все но символы в скобках), поэтому -cp [${sign,,] говорит, что нужно удалить все, кроме символа, хранящегося в ${sign}
  • <<< .... - здесь строка (позволяет передавать переменную / строку в качестве аргумента tr
  • wc -c подсчитать количество символов

ПРИМЕЧАНИЕ. Это работает, только если ${sign} содержит один символ.


A sed решение, которое должно работать независимо от количества символов в ${sign}.

$ sub='mechanic Cup cat'

Сначала мы вставляем символ новой строки перед или в каждом случае ${sign,,}:

$ sign=c
$ sed "s/\(${sign,,}\)/\n\1/g" <<< ${sub,,}
me
chani
c
cup
cat

$ sign=cup
$ sed "s/\(${sign,,}\)/\n\1/g" <<< ${sub,,} | tail +2
mechanic
cup cat

Где:

  • \(${sign,,}\) - найти шаблон, соответствующий ${sign} (все строчные буквы), и присвоить позиции 1
  • \n\1 - разместить новую строку (\n) в потоке непосредственно перед нашим шаблоном в позиции 1

В этот момент нам просто нужны строки, начинающиеся с ${sign,,}, где в игру вступает tail +2 (ie, отображать строки от 2 до n):

$ sign=c
$ sed "s/\(${sign,,}\)/\n\1/g" <<< ${sub,,} | tail +2
chani
c
cup
cat

$ sign=cup
$ sed "s/\(${sign,,}\)/\n\1/g" <<< ${sub,,} | tail +2
cup cat

И теперь мы направляемся к wc -l, чтобы получить количество строк (ie , посчитайте, сколько раз ${sign} отображается в ${sub} - без учета регистра):

$ sign=c
$ sed "s/\(${sign,,}\)/\n\1/g" <<< ${sub,,} | tail +2 | wc -l
4

$ sign=cup
$ sed "s/\(${sign,,}\)/\n\1/g" <<< ${sub,,} | tail +2 | wc -l
1
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...