我写下了以下 AWK 脚本来列出在完整路径中至少包含两个“a”字母且没有“u”字母的文件。
BEGIN {}
{
if ( (match($1, "^.*[a].*[a]+$") ) )
print $1
}
END{}
现在,您可以,脚本无法消除 'u' 字母。我必须进行哪些修改才能得到我想要的?
PS它从通过以下命令单独创建的名为“data”的文件中读取文件名及其完整路径。
find / -name '*' > data
我写下了以下 AWK 脚本来列出在完整路径中至少包含两个“a”字母且没有“u”字母的文件。
BEGIN {}
{
if ( (match($1, "^.*[a].*[a]+$") ) )
print $1
}
END{}
现在,您可以,脚本无法消除 'u' 字母。我必须进行哪些修改才能得到我想要的?
PS它从通过以下命令单独创建的名为“data”的文件中读取文件名及其完整路径。
find / -name '*' > data
由于您使用的是 bash,因此无需使用 sed、awk 或 find 等外部工具即可完成此操作。
#!/bin/bash
shopt -s globstar
for filename in **/*a*a*; do
[[ "$filename" =~ u ]] || echo "$filename"
done
如果这绝对必须是 awk,我会使用:
awk '/a.*a/ && ! /u/' data
更新:
根据 gniourf_gniourf 的礼貌警告,使用路径名扩展(globs)而不是正则表达式可能会获得更好的性能。这是一个(非科学)基准:
$ rm -f file
$ for (( i=1000000; i-- ; )); do echo u >> file; done
$ time bash -c 'while read i; do [[ $i = *u* ]]; done < file'
real 0m8.291s
user 0m6.570s
sys 0m1.717s
$ time bash -c 'while read i; do [[ $i =~ u ]]; done < file'
real 0m10.416s
user 0m8.676s
sys 0m1.735s
“用户”行是我们感兴趣的行。
这看起来好像 fileglob 的运行速度比正则表达式快约 30%,测试了一百万条记录并获得了积极的结果。
奇怪的是,当测试失败时并没有太大的改进:
$ time bash -c 'while read i; do [[ $i = *a* ]]; done < file'
real 0m8.244s
user 0m6.601s
sys 0m1.639s
$ time bash -c 'while read i; do [[ $i =~ a ]]; done < file'
real 0m9.757s
user 0m8.121s
sys 0m1.630s
在这百万次测试中,这只是 23% 的速度提升。如果这种对 shell 脚本的优化很重要(因为您正在运行数百万次测试并且不觉得有任何 CPU 周期可用),那么当您的课程从 awk 转到 bash 时,请考虑 gniourf_gniourf 的建议。
“列出在完整路径中至少包含两个 'a' 字母且没有 'u' 字母的文件”:
find / -type f -path "*a*a*" ! -path "*u*" > data
直接使用此任务的查找选项怎么样,从而data
完全避免您的文件?
find / -name '*a*a*' -not -name '*u*'
现在,如果你真的需要你的文件data
,那么 ased
就足够了:
sed -n '/a.*a/{/u/!p}' data
如果你真的想使用awk
:
awk '/a.*a/ { if ($LINE !~ /u/) print ; }' data
对于纯 bash 版本:
while read -r file; do
if [[ "$file" = *a*a* ]] && [[ "$file" != *u* ]]; then
echo "$file"
fi
done < data
data
对于完全没有文件且没有任何命令的纯 bash 版本find
,使用 glob:
#!/bin/bash
shopt -s globstar
shopt -s nullglob
for file in /**/*a*a*; do
if [[ "$file" != *u* ]]; then
echo "$file"
fi
done
如果您有很多文件(通常是 中的情况),最后一个版本将比其他版本慢得多/
。它会吞下所有的文件名,然后回显它们。具有 的解决方案find
是最好的,因为文件名将在找到时被回显(和/或处理)。
希望这可以帮助!