我正在尝试编写一个脚本来计算文件列表中某些模式的匹配数并输出其结果。基本上我想调用这样的命令:
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
我发现this answer但是它将glob模式作为脚本的唯一参数,而在我的脚本中,第一个参数是搜索模式,其余的是从glob扩展的文件。
答案 0 :(得分:2)
正如我所建议的那样,我使用了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
答案 1 :(得分:1)
你可以使用带有这样的起始索引的子串参数扩展来跳过$@
中的前n-1个值
"${@:n}"
e.g。
for FILE in "${@:2}"
do
echo $FILE
done
N.B。您的脚本没有获得'glob pattern'作为第二个参数。 调用脚本的shell会在脚本看到之前将glob扩展为空格分隔的文件列表,并将其作为参数列表传递给脚本。这就是您可以使用standard substring range expansion。
的原因答案 2 :(得分:1)
我认为这就是你想要的
#!/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'
答案 3 :(得分:1)
您可以在传递*.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 ~]#