Передать любой вывод команды в less
и это позволит разбивать на страницы, искать и еще много чего.
ls -lA / etc | less
Поскольку ваш текст отображается с помощью 'less', нажмите h
, чтобы получить помощь, прочтите и поразмышляйте.
man less
- больше читать.
Используя функции обработки строк, мы могли бы сделать это с помощью Perl следующим образом:
printf '%s\n' "$STRING" |
perl -nse '
$_.= join "", <>;
$k++ while ++($p = index($_, $s, $p));
print $k, "\n" ;
' -- -s="$SUB_STRING"
Пояснение:
° load up the whole string in $_
° index function will return the position of a substring in a string OTW returns -1
° progressively match the substring and use the position found as the starting position for the next search.
° all this while increment the counter $k depicting substring found.
Некоторые другие методы перечислены ниже:
Удалите строку и используйте регулярное выражение.
printf '%s\n' "$STRING" |
perl -slp -0777e '
$_ = () = /$s/g;
' -- -s="$s"
° Вставить строку в переменную $ _.
° передать подстроку из командной строки в perl с помощью опции -s.
° Теперь выполните сопоставление с $ _и в контексте списка получите совпадения, которые затем будут взяты в скалярном контексте для получения количества совпадений.
° опция -p автоматически печатает содержимое $ _.
Метод с использованием инструмента sed:
esc_s=$(printf '%s\n' "$SUB_STRING" |\
sed -e 's:[][\/.^$*]:\\&:g' -e 'H;1h;$!d;g;s/\n/\\n/g')
printf '%s\n' "$STRING" |
sed -ne '
$!{N;s/^/\n/;D;}
/'"$esc_s"'/{
x;p;x
s///;s/^/\n/;D
}
' | wc -l
° В качестве подготовительного шага мы идем дальше и экранируем все символы, действующие как метасимволы, в левую часть оператора s/// в подстроке, что, если не сделать, приведет к сбою sed.
° Теперь мы вливаем всю строку в пространство шаблонов.
° затем мы продолжаем печатать пустую строку, место хранения является хорошим кандидатом, и удаляем подстроку из пространства шаблона.
° промыть... вспенить... повторять до тех пор, пока присутствует подстрока.
° Затем пустые строки передаются в инструмент wc, который дает нам количество строк = количество найденных подстрок.
Это версия оболочки:
e=$STRING N=0
while
e=$(expr " $e" : " \(.*\)$SUB_STRING")
case $e in "" ) break ;; esac
do
N=$(expr "$N" + 1)
done
echo "$N"
Если у вас есть gnugrep, вы можете запустить что-то вроде
grep -zPio 'Bluetooth\s+Soft blocked: no\s+Hard blocked: no' ex.txt | grep -zc.
Вы можете использовать Python, как в этом вопросе
python -c 'print "abcdabcva".count("ab")'
Или если вы работаете с переменными оболочки:
python -c 'print("""'"$STRING"'""".count("""'"$SUB_STRING"'"""))'
В вашем случае:
python -c 'print """0: asus-wlan: Wireless LAN
Soft blocked: no
Hard blocked: no
1: asus-bluetooth: Bluetooth
Soft blocked: no
Hard blocked: no
2: phy0: Wireless LAN
Soft blocked: no
Hard blocked: no
113: hci0: Bluetooth
Soft blocked: no
Hard blocked: no""".count("""Bluetooth
Soft blocked: no
Hard blocked: no""")'
gawk '
END { print NR - 1 }
' RS='Bluetooth
Soft blocked: no
Hard blocked: no' input.txt
Пояснение
RS
-разделитель входных записей, по умолчанию новая строка. Установите его на нужную строку, и awk
разделит весь текст на записи, используя эту строку в качестве разделителя. Затем остается только вывести количество записей, вычтенных 1
в секции END
.
Использование переменных:
#!/bin/bash
STRING='0: asus-wlan: Wireless LAN
Soft blocked: no
Hard blocked: no
1: asus-bluetooth: Bluetooth
Soft blocked: no
Hard blocked: no
2: phy0: Wireless LAN
Soft blocked: no
Hard blocked: no
113: hci0: Bluetooth
Soft blocked: no
Hard blocked: no'
SUB_STRING='Bluetooth
Soft blocked: no
Hard blocked: no'
gawk 'END { print NR - 1 }' RS="$SUB_STRING" <<< "$STRING"
Сperl
:
printf '%s' "$SUB_STRING" |
perl -l -0777 -ne '
BEGIN{$sub = <STDIN>}
@matches = m/\Q$sub\E/g;
print scalar @matches' <(printf '%s' "$STRING")
Только с bash
всегда можно сделать что-то вроде:
s=${STRING//"$SUB_STRING"}
echo "$(((${#STRING} - ${#s}) / ${#SUB_STRING}))"
То есть $s
содержит $STRING
со всеми удаленными вхождениями $SUB_STRING
внутри него. Мы находим количество $SUB_STRING
, которые были удалены, вычисляя разницу в количестве символов между $STRING
и $s
и деля на длину самого $SUB_STRING
.
POSIXly вы могли бы сделать что-то вроде:
s=$STRING count=0
until
t=${s#*"$SUB_STRING"}
[ "$t" = "$s" ]
do
count=$((count + 1))
s=$t
done
echo "$count"
Если подстрока не содержит разрывов строк:
echo -n STRING | grep -Fo SUBSTRING | wc -l