这与Function to search of multiple patterns using grep
有关我想使用以下命令搜索多个模式的多个文件:
myscript *.txt pattern1 pattern2 pattern3
我尝试在上一个问题中实现代码,但它们不适用于通配符。例如,以下操作不起作用:
#!/bin/bash
ARGS=$#
if [ $ARGS -lt 2 ]
then
echo "You entered only $ARGS arguments- at least 2 are needed."
exit
fi
search() {
if [ $# -gt 0 ]
then
local pat=$1
shift
grep -i "$pat" | search "$@"
else
cat
fi
}
for VAR in $1
do
file=$VAR
shift
cat "$file" | search "$@"
done
如何创建一个可以搜索多个文件的脚本(从第一个参数中取出)来搜索多个模式(从其余参数中搜索)?
答案 0 :(得分:1)
您是否尝试使用find
和sed
?
find . -name *.txt -exec sed -n -e '/pattern1/p' -e '/pattern2/' '{}' ';'
-n
选项将确保sed不会打印所有文件,p
命令会打印匹配的行。最后,find
将获得您需要的所有文件。
修改强>
如果您想将其放入脚本中以生成sed
命令,则可以使用this trick。
编辑2:
正如@shellter所说,通常最好使用选项,并且在编写脚本时,*.txt
将由bash
扩展。为避免这种情况,您需要引用第一个参数。
像往常一样,您的问题有几种解决方案:
#! /usr/bin/env bash
set -o nounset # Throw error if variable not set
set -o errexit # Exit if error is thrown
work_dir=$PWD # directory to search from
# Reading the command line
files_pattern=${1:-}; # Save first argument as files pattern.
shift 1; # Move $1 to next argument (and propagate such as $n gets $n+1)
echo "==> Files to search follow pattern: ${files_pattern}"
_len=$#; #save the number of arguments.
for (( i=0; i<$_len; i=$i+1 )); # Go through the search patterns.
do
search_patterns[$i]=$1; # store the next search pattern
shift 1; # move $1 to next patern.
echo "==> New search pattern #$i: ${search_patterns[$i]}"
done
while read -r file; # Go through all the matching files
do
echo "==> In file: ${file}"
while read -r line; # Go though all the lines in the file
do
for regex in "${search_patterns[@]}"; # iterate trough patterns
do
[[ "${line}" =~ $regex ]] && echo "${line}";
done
done < ${file}
done < <(find $work_dir -iname $files_pattern -print) # find all the files matching file_pattern
#! /usr/bin/env bash
set -o nounset # Throw error if variable not set
set -o errexit # Exit if error is thrown
work_dir=$PWD # directory to search from
# Reading the command line
files_pattern=${1:-}; # Save first argument as files pattern.
shift 1; # Move $1 to next argument (and propagate such as $n gets $n+1)
echo "==> Files to search follow pattern: ${files_pattern}"
while [ $# -gt 0 ]; # Go through the search patterns.
do
search_patterns+="$1"; # store the next search pattern
shift 1; # move $1 to next patern.
[ $# -gt 0 ] && search_patterns+="|" #Add or option
done
echo "==> Search patterns: ${search_patterns}"
cd ${work_dir} && egrep -iR '('"${search_patterns}"')' && cd -;
#! /usr/bin/env bash
set -o nounset # Throw error if variable not set
set -o errexit # Exit if error is thrown
work_dir=$PWD # directory to search from
# Reading the command line
files_pattern=${1:-}; # Save first argument as files pattern.
shift 1; # Move $1 to next argument (and propagate such as $n gets $n+1)
echo "==> Files to search follow pattern: ${files_pattern}"
while [ $# -gt 0 ]; # Go through the search patterns.
do
search_patterns+="/$1/p;"; # store the next search pattern
shift 1; # move $1 to next patern.
[ $# -gt 0 ] && search_patterns+=" " #Add or option
done
echo "==> Search patterns: ${search_patterns}"
# Will print file names, and then matching lines
find "$work_dir" -iname "$files_pattern" -print -exec sed -n "${search_patterns}" '{}' ';'
我确信还有很多其他方法可以调整或解决这个问题,但这应该可以让你开始。
祝你好运!