Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/bash/16.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
Bash 如果第二个参数为';什么是全球模式?_Bash_Glob - Fatal编程技术网

Bash 如果第二个参数为';什么是全球模式?

Bash 如果第二个参数为';什么是全球模式?,bash,glob,Bash,Glob,我试图编写一个脚本,计算文件列表中某个模式的匹配数,并输出结果。基本上,我想这样调用命令: count-per-file.sh str_-needle*.c 并获得如下输出: Main.c: 12 Foo.c: 1 剧本: #!/bin/bash # Count occurences of pattern in files. # # Usage: # count-per-file.sh SEARCH_PATTERN GLOB_EXPR for file in "$2"; do co

我试图编写一个脚本,计算文件列表中某个模式的匹配数,并输出结果。基本上,我想这样调用命令:

count-per-file.sh str_-needle*.c

并获得如下输出:

Main.c: 12
Foo.c: 1
剧本:

#!/bin/bash
# Count occurences of pattern in files.
#
# Usage:
#   count-per-file.sh SEARCH_PATTERN GLOB_EXPR
for file in "$2"; do
    count=$(grep -a "$1" "$file" | wc -l)
    if [ $count -gt 0 ]; then
        echo "$file: $count"
    fi
done
问题是,如果我像这样调用它,那么我不知道如何循环文件列表,所以这不会输出任何内容:

count-per-file.sh str_needle *.c

我发现,但它处理的glob模式是脚本的唯一参数,而在我的脚本中,第一个参数是搜索模式,其余的是从glob展开的文件。

您可以使用子字符串参数展开和这样的开始索引来跳过
$@

“${@:n}”

e、 g

N.B.您的脚本没有将“全局模式”作为第二个参数。
在脚本看到glob之前,调用脚本的shell会将glob扩展到一个以空格分隔的文件列表,并将其作为参数列表传递给脚本。这就是你可以使用的原因。

我想这就是你想要的

#!/bin/bash
# Count occurences of pattern in files.
#
# Usage:
#   count-per-file.sh SEARCH_PATTERN GLOB_EXPR
for file in $2; do                               #UNQUOTE THIS TO EXPAND GLOB
    count=$(grep -a "$1" "$file" | wc -l)
    if [ $count -gt 0 ]; then
        echo "$file: $count"
    fi
done
然后在引号中传递glob,这样它就不会在命令行上展开

count-per-file.sh str_needle '*.c'

您可以在传递
*.c
时添加引号,在
for
循环中使用引号时删除引号,这样就可以了

[root@client1 ~]# cat  count-per-file.sh
#!/bin/bash
# Count occurences of pattern in files.
#
# Usage:
#   count-per-file.sh SEARCH_PATTERN GLOB_EXPR
for file in $2; do
    count=$(grep -a "$1" $file | wc -l)
    if [ $count -gt 0 ]; then
        echo "$file: $count"
    fi
done
[root@client1 ~]# bash count-per-file.sh str_needle "*.c"
file.c: 1
Main.c: 12
[root@client1 ~]#

正如建议的那样,我使用了
shift
,它似乎“弹出”了第一个参数。以下是我的工作脚本:

#!/bin/bash
# Count occurences of pattern in files.
#
# Usage:
#   count-per-file.sh SEARCH_PATTERN GLOB_EXPR
search_pattern="$1"
shift

for file in "$@"; do
    count=$(grep -aiE "$search_pattern" "$file" | wc -l)
    if [ $count -gt 0 ]; then
        echo "$file: $count"
    fi
done

如果像
count-per-file.sh stru needle*.c
那样调用它,那么第二个参数将不是
*.c
;您的shell将其扩展为
Main.c
Foo.c
(作为第二个和第三个参数)。@Biffen好的,如果我的第一个参数始终是搜索模式,我将如何循环这些文件?
shift
,然后是
for file
。你知道grep-ocstr_needle*.c做你想做的事,对吧?而且,
grep…|wc-l
不会给出出现的次数,只会给出行数?
shift
然后,
对于“$@”中的文件,我将阅读
shift
谢谢。
grep
命令类似,但它列出了所有文件,即使没有匹配项,而我的脚本只列出了至少有一个匹配项的文件。这不起作用,因为它只进行了循环的一次迭代,
$file
是全局扩展中的第一个文件。哦,它确实起作用,我必须用引号传递glob参数,谢谢
shift
没有弹出;它改变了。pop就是删除列表中的最后一个。他非正式地使用了“pop”。
#!/bin/bash
# Count occurences of pattern in files.
#
# Usage:
#   count-per-file.sh SEARCH_PATTERN GLOB_EXPR
search_pattern="$1"
shift

for file in "$@"; do
    count=$(grep -aiE "$search_pattern" "$file" | wc -l)
    if [ $count -gt 0 ]; then
        echo "$file: $count"
    fi
done