Как выполнить поиск от одного символа или шаблона к другому?

Похоже, вы хотите подсчитать количество полей -с разделителями табуляции в файле. Для этого пришлось бы разбивать строку ввода на табы и считать их. awkможет сделать это автоматически, а также имеет специальную переменную для результирующего количества полей, NF.

Если вы хотите распечатать все строки с 996 полями (995 вкладок):

awk -F '\t' 'NF == 996' <file

Это сокращенный способ записи

awk 'BEGIN { FS = "\t" } NF == 996 { print }' <file

где printозначает print $0, т.е. вывести входную запись (строку ), а FS— разделитель полей ввода.

Всякий раз, когда вы извлекаете строки текста из файла и передаете их в awkили sedили подобному инструменту в цикле, всегда есть более эффективный способ выполнить ту же операцию. Обратите внимание, что приведенные выше команды вызывают awkтолько один раз, тогда как ваше решение (, если бы оно правильно передало данные в awk), вызывало бы awkдля каждой строки в файле.

1
13.05.2020, 21:55
2 ответа

В zshвы можете сделать:

$ str='The brown fox jumps over the lazy dog'
$ print -r -- ${(SM)str#b*s}
brown fox jumps

Оператор ${str#pattern}ksh удаляет кратчайшую строку, совпадающую с pattern, из начала строки.S(для подстроки)флаг расширения параметра расширяет его таким образом, что шаблон не ограничивается соответствием в начале , но как можно ближе к началу. Флаг M(для сопоставленного)заставляет эти операторы расширения расширяться до того, что совпадает, вместо удаления совпадающей части.

Использование ##вместо #дает вам самый длинный вместо самый короткий и %/ %%поиск шаблона с конца строки.

Вы также можете выполнить сопоставление PCRE и использовать его *?не--нежадный оператор с:

$ zmodload zsh/pcre
$ [[ $str -pcre-match 'b.*?s' ]] && print -r -- $MATCH
brown fox jumps

или:

$ set -o rematchpcre
$ [[ $str =~ 'b.*?s' ]] && print -r -- $MATCH
brown fox jumps

Однако для вашего конкретного случая использования я бы просто сделал:

mv file.txt ~2

Чтобы переместить файл во второй каталог в вашем каталоге каталогов.

При правильной настройке завершение покажет вам, что эти ~<number>соответствуют после нажатия вкладки после~+:

$ mv file ~+Tab
Completing directory stack
1 -- ~/install/cvs/zsh/Config
2 -- ~
3 -- /usr
4 -- ~bin
5 -- ~
6 -- /

Минимум ~/.zshrcдля получения этого вывода будет выглядеть так:

set -o autopushd
autoload -Uz compinit
compinit
zstyle ':completion:*' menu select=0
zstyle ':completion:*' verbose true
zstyle ':completion:*' format 'Completing %d'

(см. также compinstallдля более удобной для начинающих -настройки завершения ).

3
28.04.2021, 23:14

Использовать отложенное сопоставление(.*?)из регулярного выражения PCRE:

$ str='The brown fox jumps over the lazy dog'

$ grep -Po 'b.*?s' <<<"$str"
brown fox jumps

$ grep -Po 'the l.*?g' <<<"$str"
the lazy dog

Существует аналогичное решение для более простых регулярных выражений, но работает только для одиночных символов (справа):

$ grep -o 'b[^s]*s' <<<"$str"
brown fox jumps

$ grep -o 'the l[^g]*g' <<<"$str"
the lazy dog

Все вышеперечисленное будет соответствовать первому исходному тексту, а затем первому конечному тексту (включенному ).

3
28.04.2021, 23:14

Теги

Похожие вопросы