Grep variable expansion within "find -exec sh -c"

grep the value of a variable
grep with variable example
how to pass variable value in grep command
grep variable pattern
grep with variable in regex
grep output to variable
bash variable within grep
grep variable in file

I've written a script that loops through word documents to match words within them. Below is an example that works, and finds the number 43. Following that is a script that doesn't work. All I want to do is have the number 43 as a variable at the start of my script, but it doesn't seem to expand properly. Any ideas how I can have 43 as a variable in my script rather than hard coding it?

Script that works:

find . -type f -name '*.docx' -exec sh -c '
  for file do
docx2txt "$file" 2>/dev/null - | grep -i --color "43" && printf "\033[1;32mFound in ${file}\033[0m\n"
#readlink -f "$file"
  done
' sh {} +

Script that doesn't work:

scan_var=43
find . -type f -name '*.docx' -exec sh -c '
  for file do
docx2txt "$file" 2>/dev/null - | grep -i --color "$scan_var" && printf "\033[1;32mFound in ${file}\033[0m\n"
#readlink -f "$file"
  done
' sh {} +

From a security perspective, you should be using export to expose variables to subprocesses through the environment, not substituting those variables into strings parsed as code (which lends itself to shell injection attacks).

That is:

export scan_var=43  ## the **only** change is to this line!

# only modifications to code below are formatting with no functional impact
# ...well, and safer printf use (to not expand format strings in filenames)
find . -type f -name '*.docx' -exec sh -c '
  for file do
    docx2txt "$file" 2>/dev/null - \
    | grep -i --color "$scan_var" \
    && printf "\033[1;32mFound in %s\033[0m\n" "$file"
  done
' sh {} +

Parameter expansion in grep, Either: grep -iEo 'entry=G_(1234|2345)'. That is use the alternation operator of extended ( E ) regular expressions. Or with shells that support� If the ith character of this environment variable's value is 1, do not consider the ith operand of grep to be an option, even if it appears to be one. A shell can put this variable in the environment for each command it runs, specifying which operands are the results of file name wildcard expansion and therefore should not be treated as options.

sh -c forks a subprocess, where the variable isn't visible, see Charles' answer for a fix.

Another technique to get a variable into -exec sh -c is to use it as a parameter. Consider

$ var=43
$ sh -c 'echo "$var"'         # Expands to nothing

$ sh -c 'echo "$1"' sh "$var"  # Gets variable value into sh -c
43

Notice that the first parameter for sh -c after the command is used as $0 within sh -c (the name of the process).

Applied to your command:

scan_var=43
find . -type f -name '*.docx' -exec sh -c '
    scan_var=$1
    shift
    for file do
        echo docx2txt "$file" 2>/dev/null - \
            | grep -i --color "$scan_var" \
            && printf "\033[1;32mFound in ${file}\033[0m\n"
        # readlink -f "$file"
    done
' sh "$scan_var" {} +

The value of the first parameter is read into scan_var and the parameter then discarded with shift.

How do I use string variable (which contains double quote) in grep, When you use single quotes the the pattern is taken as a literal string, so grep '" name": $DNS_RECORD_NAME'. will try to match the literal� grep for expression containing variable (1 answer) Closed 6 years ago . I have written the following shell to count the number of lines starting with the pattern of " A valA B valB".

You are atempting to use a variable inside single quotes. Adjust the grep command line:

grep -i --color "'"$scan_var"'" && ...

This will close the single-quote from your find -exec before $scan_var and start a single-quote for the rest of the code.

How to assign a grep command value to a variable in Linux/Unix , But, you can store output to variable in your shell scripts. ADVERTISEMENTS. Syntax: Command substitution. Command substitution means� 3.5.3 Shell Parameter Expansion. The ‘$’ character introduces parameter expansion, command substitution, or arithmetic expansion.The parameter name or symbol to be expanded may be enclosed in braces, which are optional but serve to protect the variable to be expanded from characters immediately following it which could be interpreted as part of the name.

When to use single-quote, double-quote in grep?, VAR="serverfault" grep '$VAR' file1 grep "$VAR" file1. The first grep will look for the literal string "$VAR1" in file1. The second will expand the "$VAR" variable� Regular Expressions in grep. Regular Expressions is nothing but a pattern to match for each input line. A pattern is a sequence of characters. Following all are examples of pattern:

Variables and Expansions, In fact, the rm command will never even see our pathname expansion pattern. You could put a bash house or a grep shack or a firefox tower on the land. Hi, I'm currently trying to use variables in grep on my script. Printing the variable via echo works fine. Also, if I hard coded the date of the appointment it works just fine. But, if I try to use th | The UNIX and Linux Forums

[SOLVED] Using variables in a shell script with find and grep, For those familliar to dos (batch) using %variable% in batch and %variable in the I believe I am correct about "grep" not being able to expand braces {}, but I� grep with search terms defined by a variable. Hi, I have a good grasp of grep() and gsub() for finding and extracting character strings. However, I cannot figure out how to use a search term that is

Comments
  • Duh, of course. Single quotes had nothing to do with it.
  • I still think your answer was a valuable one, teaching a useful technique -- if you don't plan on undeleting it after editing, I might extend this one to cover the argv approach.
  • Consider the case where scan_var=$'42$(rm -rf ~)\'$(rm -rf ~)\'' -- it can't be safely substituted into code in any kind of surrounding quotes. By contrast, passing it through the environment is 100% safe.
  • (Benjamin W's answer is also safe for all possible values; this is the only one presently available on the question that isn't).
  • Thanks for the constructive criticism @CharlesDuffy.