Jay Wisniewski
Jay Wisniewski

Reputation: 45

looping grep function

So I was building a script for a co-worker so she can easily scan files for occurrences of strings. But I am having trouble with my grep command.

    #!/bin/bash -x

filepath() {
echo -n "Please enter the path of the folder you would like to scan, then press [ENTER]: "
read path
filepath=$path
}

filename () {
echo -n "Please enter the path/filename you would like the output saved to, then press [ENTER]: "
read outputfile
fileoutput=$outputfile
touch $outputfile
}
searchstring () {
echo -n "Please enter the string you would like to seach for, then press [ENTER]: "
read searchstring
string=$searchstring
}
codeblock() {
for i in $(ls "${filepath}")
do
  grep "'${string}'" "$i" | wc -l | sed "s/$/ occurance(s) in "${i}" /g" >> "${fileoutput}"
done
}

filepath
filename
searchstring
codeblock
exit

I know there are a lot of extra variable "redirects" Just practicing my scripting. Here is the error I am receiving when I run the command.

+ for i in '$(ls "${filepath}")'
+ grep ''\''<OutageType>'\''' *filename*.DONE.xml
+ wc -l
+ sed 's/$/ occurance(s) in *filename*.DONE.xml /g'
grep: *filename*.DONE.xml: No such file or directory 

However if I run the grep command with the wc and sed functions from CLI it works fine.

# grep '<OutageNumber>' "*filename*.DONE.xml" | wc -l | sed "s/$/ occurance(s) in "*filename*.DONE.xml" /g"
13766 occurance(s) in *filename*.DONE.xml

Upvotes: 0

Views: 72

Answers (1)

janos
janos

Reputation: 124656

There are several things going wrong here.

for i in $(ls "${filepath}")

The value of filepath is *filename*.DONE.xml, and if you assume that the * get expanded there, that won't happen. A double-quoted string variable is taken literally by the shell, the * will not get expanded.

If you want wildcard characters to be expanded to match filename patterns, then you cannot double-quote the variable in the command.

Next, it's strongly discouraged to parse the output of the ls command. This would be better:

for i in ${filepath}

And this still won't be "perfect', because if there are no files matching the pattern, then grep will fail. To avoid that, you could enable the nullglob option:

shopt -s nullglob
for i in ${filepath}

Finally, I suggest to eliminate this for loop, and use the grep command directly:

grep "'${string}'" ${filepath} | ...

Upvotes: 2

Related Questions