0

Is there any command support to find the "exact" string(s) in the given input?

For example:

pattern='s.'
sample_input='abcdsasd kmsa so
msd ks'
some_command $sample_input $pattern 

I wish it output:

sa
sd
sa
so
sd

I find a duplicated question: https://stackoverflow.com/questions/6259747/print-all-matches-of-a-regular-expression-from-the-command-line

0
2

If your grep has the -o (or --only-matching) switch and your shell supports here strings:

grep -o -- "$pattern" <<<"$sample_input"
0

we prepare another var p which holds the escaped version of pat variable.

pat='s.'
p=${pat//\//\\/}
sample_input='abcdsasd kmsa so
msd ks'

Using perl in slurp mode so that the whole sample input is in one record $_

$ printf '%s\n' "$sample_input" | pat="$pat" \
perl -ln -0777e 'print for s/\n\z//r =~ /$ENV{pat}/sg'

Here we make use of sed in a pseudo code:

_DO_=':a'    _UNTIL_NOPAT_=${_DO_/:/t }
_SAVE_='h'   _RETRIEVE_='g'
_RM_PAT_='s/'"$p"'\(.*\)/\1/'
_SLURP_='$!{N;s/^/\n/;D;}'
_CHOMP_R='s/\('"$p"'\).*/\1/'
_CHOMP_L_n_PRNT='s/.*\('"$p"'\)/\1/p'

printf '%s\n' "$sample_input" |
sed -ne "
  ${_SLURP_}
  ${_DO_}
      ${_SAVE_}
          ${_CHOMP_R}
          ${_CHOMP_L_n_PRNT}
      ${_RETRIEVE_}
      ${_RM_PAT_}
  ${_UNTIL_NOPAT_}
"
1
  • Yeah that was a typo. Fixed. Thanks. Aug 10 '20 at 12:26
0

In zsh, to find all the strings that match a shell pattern, you can use this approach:

pattern='s?' # equivalent of regexp 's.'
sample_input='abcdsasd kmsa so
msd ks'

set -o extendedglob
matches=()
: ${sample_input//(#m)$~pattern/${matches[1+$#matches]::=$MATCH}}

Which here gives:

$ print -r -- $matches
sa sd sa so sd

That has several advantages over an approach using GNU grep -o:

  • it works whatever bytes or characters $sample_input may contain. In particular NUL and NL and bytes not forming part of valid characters (which would still be matched by ? or *).
  • it doesn't have to rely on a GNUism
  • zsh patterns are significantly more expressive than standard regular expressions.

There are a few PCRE operators that don't have an equivalent in zsh wildcards (such as look around ones). If you wanted to use those, you could use zsh's builtin pcre_match command. The manual (see info zsh pcre_match) has an example that does just that: extract matches into an array.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.