I want to use grep
to search for matching strings in the file, but because the file is too big, I only search for the first 500 lines.
I wrote in the shell script:
#!/bin/bash
patterns=(
llc_prefetcher_operat
to_prefetch
llc_prefetcher_cache_fill
)
search_file_path="mix1-bimodal-no-bop-lru-4core.txt"
echo ${#patterns[*]}
cmd="head -500 ${search_file_path} | grep -a "
for(( i=0;i<${#patterns[@]};i++)) do
cmd=$cmd" -e "\"${patterns[i]}\"
done;
echo $cmd
$cmd >junk.log
The result of running the script is:
3
head -500 mix1-bimodal-no-bop-lru-4core.txt | grep -a -e "llc_prefetcher_operat" -e "to_prefetch" -e "llc_prefetcher_cache_fill"
head: invalid option -a
Try'head --help' for more information.
On the penultimate line, I printed out the string of the executed command. I ran it directly on the command line and it was successful. That is the following sentence.
head -500 mix1-bimodal-no-bop-lru-4core.txt | grep -a -e "llc_prefetcher_operat" -e "to_prefetch" -e "llc_prefetcher_cache_fill"
Note that in the grep
command, if I do not add the -a
option, there will be a problem of matching the binary file
.
Why does this problem occur? Thank you!
Instead of trying to build a string holding a complex command, you're better off using grep
's -f
option and bash
process substitution to pass the list of patterns to search for:
head -500 "$search_file_path" | grep -Faf <(printf "%s\n" "${patterns[@]}") > junk.log
It's shorter, simpler and less error prone.
(I added -F
to the grep
options because none of your example patterns have any regular expression metacharacters; so fixed string searching will likely be faster)
The biggest problem with what you're doing is the |
is treated as just another argument to head
when $cmd
is word split. It's not treated as a pipeline delimiter like it is when a literal one is present.
Collected from the Internet
Please contact [email protected] to delete if infringement.
Comments