Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/shell/5.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Shell命令在Shell中工作,但在Shell脚本中不工作_Shell_Grep - Fatal编程技术网

Shell命令在Shell中工作,但在Shell脚本中不工作

Shell命令在Shell中工作,但在Shell脚本中不工作,shell,grep,Shell,Grep,我试图编写一个unix shell脚本来搜索给定文本的所有头文件,然后查找每个头文件包含在其他文件中的次数 我的问题在第二部分,搜索其他文件中包含的命令可以从命令行运行,但它不会从shell脚本打印任何内容 array=( $(grep 'regexToSearch' -rl --include="*.h" pathToFiles) ) for item in "${array[@]}" do filename=$(echo ${item} | grep -o '[^/]*.h')

我试图编写一个unix shell脚本来搜索给定文本的所有头文件,然后查找每个头文件包含在其他文件中的次数

我的问题在第二部分,搜索其他文件中包含的命令可以从命令行运行,但它不会从shell脚本打印任何内容

array=( $(grep  'regexToSearch' -rl --include="*.h" pathToFiles) )

for item in "${array[@]}"
do
    filename=$(echo ${item} | grep -o '[^/]*.h')
    incstring="#include[ ]*\"$filename\""
    echo $incstring
    echo "--------------------"
    filelist=$(grep '$incstring' -rl --include=*.{h,cpp} pathToFiles)
    echo $filelist
    echo "--------------------"
done
结果如下:

#include[ ]*"header1.h"
--------------------
// Second grep output for first file should be here
--------------------
#include[ ]*"header2.h"
--------------------
// Second grep output for second file should be here
--------------------
#include[ ]*"header3.h"
--------------------
// Second grep output for third file should be here
--------------------

您正在该命令中使用单引号:

    filelist=$(grep '$incstring' -rl --include=*.{h,cpp} pathToFiles)
单引号禁止变量扩展。也就是说,您要查找的是文本字符串
$incstring
,而不是该变量的内容。如图所示,此命令在命令行上也不起作用

bash(1)
手册页:

将字符括在单引号中会保留引号中每个字符的文字值。单人间 引号不能出现在单引号之间,即使前面有反斜杠

将单引号替换为双引号:

    filelist=$(grep "$incstring" -rl --include=*.{h,cpp} pathToFiles)

首先,形成数组的方式不可靠——如果头文件包含
IFS
中的字符、通配符等,则会导致一些令人惊讶的失败

pathToFiles=.

# form the headers array in a manner robust against all possible filenames
headers=()
while IFS='' read -r -d '' filename; do
  headers+=( "${filename#${pathToFiles}/}" )
done < <(grep -e "$regexToSearch" -Z -rl --include='*.h' "$pathToFiles")

for header in "${headers[@]}"; do
  echo "--- ${header}"
  # instead of capturing content, emit it directly to stdout
  grep -F -e '#include "'"$header"'"' -rl --include='*.h' --include='*.cpp' "$pathToFiles"
  echo "---"
done
pathToFiles=。
#以对所有可能的文件名都具有鲁棒性的方式形成headers数组
标题=()
而IFS=''read-r-d''文件名;做
头文件+=(“${filename}${pathToFiles}/}”)

完成<您正在将
文件列表
从数组(原始)转换为字符串,这将极大地改变其含义。并不是说它被正确地放入了一个数组中(输出只是被字符串分割,包含了所有的bug/misfeatures),所以这实际上并没有更大的错误。。。但是以正确的方式形成数组可能是更好的解决方案。而且,
--include=“*.h”
实际上是理想的用法。检查手册页上的GNU
grep
——它需要并计算文字模式。抱歉——不是“文字模式”,而是“文字全局模式”。简而言之,--include的理想用法不是shell求值,而是grep递归代码中的
fnmatch()
-样式匹配。为什么只捕获
incstring
filelist
来打印它们,而不让生成它们的命令直接发送到stdout?