2

I have a file1.txt with the below contents:

time="2016-04-25T17:43:11Z" level=info msg="SHA1 Fingerprint=9F:AD:D4:FD:22:24:20:A2:1E:0C:7F:D0:19:C5:80:42:66:56:AC:6F"

I want the file to look as below:

9F:AD:D4:FD:22:24:20:A2:1E:0C:7F:D0:19:C5:80:42:66:56:AC:6F  

Actually, I need to pass the command as a string. That is why the bash command needs to be encapsulated in a string with double quotes. However, when i include

 " grep -Po '(?<=Fingerprint=)[^"]*' "   

I don't get the desired output. It seems that i need to escape the double quotes correctly.

meallhour
  • 13,921
  • 21
  • 60
  • 117
  • This is arguably duplicative of http://stackoverflow.com/questions/2005192/how-to-execute-a-bash-command-stored-as-a-string-with-quotes-and-asterisk – Charles Duffy Apr 26 '16 at 16:45
  • ...btw, bash and POSIX sh are different in some quite pertinent ways (Bourne shell differs still further, but isn't present on anything Red Hat has ever shipped, so your tagging excludes it). I included a bash-only section in my answer, but if you were only tagging for one of the two it would have been clearer whether that was acceptable. – Charles Duffy Apr 26 '16 at 16:52

1 Answers1

5

To answer the literal question, you can use a backslash to escape literal double quotes in your command. However, for the reasons given in BashFAQ #50, this is exceedingly poor practice:

# Avoid this absent a very good reason
grep_cmd_str="grep -Po '(?<=Fingerprint=)[^\"]*'" 
eval "$grep_cmd_str" <file1.txt # eval is necessary, with all the issues that implies

Better practice when you need to store a simple command (with no redirections or other shell constructs)[1] in a variable is to use an array[2], not a scalar variable, to hold its arguments:

# Use this principally if you need to dynamically build up an argument list
grep_args=( grep -Po '(?<=Fingerprint=)[^"]*' )
"${grep_args[@]}" <file1.txt

If you don't have any constraints that require you to use either of the above, consider a function (which does allow redirections and shell constructs so long as they're hardcoded):

# Use this whenever possible, in preference to the above
grep_fp() { grep -Po '(?<=Fingerprint=)[^"]*' "$@"; }
grep_fp <file1.txt

[1] - Not evaluating shell constructs, in this context, is a security feature: it protects you against malicious filenames or similar content in values which have been substituted into the value you're using as a command.

[2] - Note that arrays are not available in POSIX sh, which your question is also tagged for. That said, similar functionality is available by overriding "$@" (presumably within a limited scope, such as a function, such that its original value is preserved).

Charles Duffy
  • 280,126
  • 43
  • 390
  • 441