首页 > 解决方案 > 可以在命令行上运行,但不能在 shell 脚本中运行?

问题描述

我想用它grep来搜索文件中匹配的字符串,但是因为文件太大,我只搜索前500行。

我在shell脚本中写道:

#!/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

运行脚本的结果是:

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.

在倒数第二行,我打印出执行命令的字符串。我直接在命令行上运行,成功了。也就是下面这句话。

 head -500 mix1-bimodal-no-bop-lru-4core.txt | grep -a -e "llc_prefetcher_operat" -e "to_prefetch" -e "llc_prefetcher_cache_fill"

注意,在grep命令中,如果我不添加-a选项,会出现matching the binary file.

为什么会出现这个问题?谢谢!

标签: shellgrep

解决方案


与其尝试构建一个包含复杂命令的字符串,不如使用grep'-f选项和bash进程替换来传递要搜索的模式列表:

head -500 "$search_file_path" | grep -Faf <(printf "%s\n" "${patterns[@]}") > junk.log

它更短、更简单、更不容易出错。

(我添加-Fgrep选项中是因为您的示例模式都没有任何正则表达式元字符;因此固定字符串搜索可能会更快)


您正在做的最大问题是|被视为head何时$cmd分词的另一个论点。它不像存在文字时那样被视为管道分隔符。


推荐阅读