You are not logged in.
I have a simple bash script where I am trying to pass the bash script parameters to a grep in the script:
#!/bin/bash
grepargs=""
for var in "$@"; do grepargs+="-e "; grepargs+="$var "; done
echo "${grepargs% }|" # eliminate trailing space
grep ${grepargs% } file.txt
If I run the script with two words as argument everything is fine:
$ myscript word1 word2
-e word1 -e word2|
However, I want to be able to run the script also with a sentence as an argument, like this:
$ myscript word1 "word2 word3"
-e word1 -e word2 word3|
grep: word3: File or directory not found
$ myscript word1 '"word2 word3"'
-e word1 -e "word2 word3"|
grep: word3": File or directory not found
The first syntax won't work obviously but why does not the second syntax work?
I get the same error message in both cases, although the "${grepargs% }" variable seems to be correct in the second case!
Last edited by tethys (2024-05-02 20:34:42)
Offline
Minimal fix:
- grep ${grepargs% } file.txt
+ grep "${grepargs% }" file.txt
Better script:
#!/bin/sh
grepargs=$(printf -- '-e "%s" ' "$@")
eval grep $grepargs file.txt
Best script:
printf '%s\n' "$@" | grep -f - file.txt
Last edited by Trilby (2024-05-02 18:56:21)
"UNIX is simple and coherent" - Dennis Ritchie; "GNU's Not Unix" - Richard Stallman
Offline
Wow, thank you Trilby! Such a simple solution for my original script!
I am not familiar with "printf" but I tested it, it works, and it is better than my original script so I will adopt it: with "printf" I do not have to double-quote the arguments of the script (i.e. I can use "word2 word3" instead of '"word2 word3"')!
Offline
I might be missing something :
#!/bin/bash
args=( "$@" )
echo "$(IFS='|'; echo "${args[*]}")"
$ myScript a 'b c' 'd e f'
a|b c|d e f
$
though, args array is not necessary :
#!/bin/bash
echo "$(IFS='|'; echo "$*")"
$ myScript.new a 'b c' 'd e f'
a|b c|d e f
$
Last edited by sukolyn (2024-05-03 00:04:05)
Offline
sukolyn, what are you trying to show there? How does that relate to this thread?
"UNIX is simple and coherent" - Dennis Ritchie; "GNU's Not Unix" - Richard Stallman
Offline
tethys wants to build a regex expression from script's parameters, doesn't he ?
this is what I show.
Offline
It looks like you are building grep's parameter list dynamically. You sort of have to think like the bash parser. There is a snippet below that builds the parameters in an array, which bash will parse into words correctly. You might want to look at using a case statement in a loop so you could expand what your script can do. Have fun.
#!/bin/bash
# Usage: ./cmd p1 p2 -- file_to_search
declare -a gp=()
declare -- i=1 file=''
while (( i <= ${#@} )); do
if [[ "${1}" == '--' ]]; then
file="${2}"
break
fi
# add to array
gp+=('-e')
gp+=("$1")
shift 1
done
# Print array contents
declare -p gp
echo
# Execute the command
if (( "${#gp}" >= 2 )); then
echo grep "${gp[@]}" "${file:?Missing file}"
grep "${gp[@]}" "${file:?Missing file}"
else
printf -- 'Less then 2 parameters\n'
fi
Offline
Thank you all for your inputs.
What I want is to build a grep of the kind
grep [OPTION...] -e PATTERNS ... [FILE...]
inside a bash script. The bash script itself filters the output of a log file like this:
tail -f file.log | grep -e PATTERN1 -e PATTERN2 ...
And I want to be give the PATTERNS as parameters to the bash script. Actually I do not need regex, but I want to be able to filter certain sentences (containing spaces) in the "file.log".
Offline
grep -e pat1 -e pat2 is equivalent to grep -E 'pat1|pat2'
Actually I do not need regex
each expression given to grep is a regex.
Last edited by sukolyn (2024-05-03 11:58:35)
Offline