Was*_*haW 2 grep find shell-script filenames
我想找到一个使用多种模式的文件。
这是我的原始命令:但是键入时间很长并且xargs zgrep
是多余的。想象一下,如果我有 10 个或更多的模式要输入?
find -mtime -$a -type f ! -name "*.bak*" | xargs zgrep -il "$b" | xargs zgrep -il "$c" | xargs zgrep -il "$d" | xargs zgrep -il 'ST.997' | sort -u
Run Code Online (Sandbox Code Playgroud)
我想要更少的字符来输入,例如:
find -mtime -$a -type f ! -name "*.bak*" | xargs zgrep -il "$b && $c && $d" | sort -u
Run Code Online (Sandbox Code Playgroud)
编辑:如果您注意到模式与$
. 那是因为命令在脚本中,并且这些变量具有字符串/数字值。
我将使用它来改进我的脚本,尤其是它的运行时间。
如果您想避免为每个模式一次又一次地解压缩文件,您可以执行以下操作:
PATTERNS='foo
bar
baz' find . -mtime -"$a" -type f ! -name "*.bak*" -exec awk -v q=\' '
function shquote(s) {
gsub(q, q "\\" q q, s)
return q s q
}
BEGIN {
n = split(ENVIRON["PATTERNS"], pats, "\n")
for (arg = 1; arg < ARGC; arg++) {
file = ARGV[arg]
cmd = "gzip -dcf < " shquote(file)
for (i = 1; i <= n; i++) notfound[pats[i]]
left = n
while (left && (cmd | getline line) > 0) {
for (pat in notfound) {
if (line ~ pat) {
if (!--left) {
print file
break
}
delete notfound[pat]
}
}
}
close(cmd)
}
exit
}' {} +
Run Code Online (Sandbox Code Playgroud)
请注意,模式被视为awk
模式,这类似于grep -E
/支持的扩展正则表达式egrep
。对于不区分大小写的匹配,您可以添加-v IGNORECASE=1
if using GNU awk
,或者可移植地更改为:
PATTERNS='foo
bar
baz' find . -mtime -"$a" -type f ! -name "*.bak*" -exec awk -v q=\' '
function shquote(s) {
gsub(q, q "\\" q q, s)
return q s q
}
BEGIN {
n = split(tolower(ENVIRON["PATTERNS"]), pats, "\n")
for (arg = 1; arg < ARGC; arg++) {
file = ARGV[arg]
cmd = "gzip -dcf < " shquote(file)
for (i = 1; i <= n; i++) notfound[pats[i]]
left = n
while (left && (cmd | getline line) > 0) {
line = tolower(line)
for (pat in notfound) {
if (line ~ pat) {
if (!--left) {
print file
break
}
delete notfound[pat]
}
}
}
close(cmd)
}
exit
}' {} +
Run Code Online (Sandbox Code Playgroud)
(假设模式没有像 那样的非标准 ERE 扩展名\S
,它将被转换为\s
)。
您可以将该awk
命令放在zgrep-many
脚本中以使其更易于使用。就像是:
#! /bin/sh -
usage() {
cat >&2 << EOF
Usage: $0 [-e <pattern>] [-f <file] [-i] [pattern] files
List the files for which all the given patterns are matched.
EOF
exit 1
}
ignorecase=
PATTERNS=
export PATTERNS
NL='
'
sep=
while getopts e:f:i opt; do
case $opt in
(e) PATTERNS=$PATTERNS$sep$OPTARG; sep=$NL;;
(f) PATTERNS=$PATTERNS$sep$(cat < "$OPTARG") || exit; sep=$NL;;
(i) ignorecase='tolower(';;
(*) usage;;
esac
done
shift "$((OPTIND - 1))"
if [ -z "$PATTERNS" ]; then
[ "$#" -gt 0 ] || usage
PATTERN=$1; shift
fi
[ "$#" -eq 0 ] && exit
exec awk -v q=\' '
function shquote(s) {
gsub(q, q "\\" q q, s)
return q s q
}
BEGIN {
n = split('"$ignorecase"'ENVIRON["PATTERNS"]'"${ignorecase:+)}"', pats, "\n")
for (arg = 1; arg < ARGC; arg++) {
file = ARGV[arg]
cmd = "gzip -dcf < " shquote(file)
for (i = 1; i <= n; i++) notfound[pats[i]]
left = n
while (left && (cmd | getline line) > 0) {
'"${ignorecase:+line = tolower(line)}"'
for (pat in notfound) {
if (line ~ pat) {
if (!--left) {
print file
break
}
delete notfound[pat]
}
}
}
close(cmd)
}
exit
}' "$@"
Run Code Online (Sandbox Code Playgroud)
用作:
find ... -exec zgrep-many -ie foo -e bar -e baz {} +
Run Code Online (Sandbox Code Playgroud)
例如。