问题要我列出存储的所有文件,/usr/bin
其中文件名仅包含小写英文字母并包含“文件”一词。
例如,nsrfile
andfile
应该在输出中
这是我实现此目的的代码
ls /usr/bin | grep '\<[a-z]*file[a-z]*\>'
这是我得到的部分结果。
file
nsrfile
grub2-file
systemd-tmpfiles
但是,问题说文件名只能包含小写英文字母,不能包含斜杠-
甚至grub2-file
包含一个数字
我应该如何更改我的命令?
答案1
期望与警告
您的作业可能期望您得到grep
的输出ls
,也许是这样的:
cd /usr/bin
ls | grep '^[a-z]*$' | xargs grep file
当您要求ls
提供文件名时,请使用仅以小写字母开头 ( ) 和结尾 ( )grep
的过滤器- 零个或多个 ( );然后,您要求grep 每个传入的文件名以查找字符串“file”。^
$
*
xargs
一旦任何文件名(不太可能位于 /usr/bin 中)包含换行符,就会立即遇到麻烦。 (其中包含空格的文件Some File Name
将被 grep 排除。)用一个人为的示例来说明这一点:
cd ~/tmp/usr/bin
touch a$'\n'b
ls | grep '^[a-z]*$' | xargs grep file
grep: a: No such file or directory
grep: b: No such file or directory
在上面的示例中,ls
将以下内容写入 grep 的管道中:
a
b
Grep 正确地将这两个“文件名”通过管道传递给 xargs,然后 xargs 认为它有两个要 grep 的文件名,因此它运行:
grep file a b
...然后抱怨丢失的文件。
建议
虽然这不是预期的,但我建议使用以下更安全的选项(假设使用 bash shell):
shopt -s extglob
grep -l file /usr/bin/!(*[^a-z]*)
这将打开bash 的扩展通配符功能。然后,您要求在 /usr/bin 中的文件中grep
列出包含字符串“file”的文件名 ( )-l
不是( !
) 匹配模式:“任何内容 ( *
) 后跟任何单个 ( [ ... ]
) 非 ( ^
) -小写字母 ( a-z
),后跟任何内容 ( *
)。换句话说,仅包含以下内容的文件仅有的他们的名字中的小写字母。
答案2
我会做什么:
printf '%s\n' /usr/bin/* |
grep '\<[a-z]*file[a-z]*\>' | grep -Ev '[0-9]|-'
解释 :
grep -v
是一个反向 grep。有两种模式:[0-9]
和-
答案3
两种解决方案:
一个 shell 循环:
for name in /usr/bin/*file*; do
case "${name##*/}" in
*[!a-z]*) ;;
*) printf '%s\n' "$name"
esac
done
/usr/bin
这首先生成一个基本名称匹配的路径名列表*file*
,然后测试这些基本名称是否还包含非小写字母的字符。如果未找到非小写字母,则打印路径名。
这也可能会找到满足条件的目录名称。如果这不是想要的,就这样做
[ ! -f "$name" ] && continue
在语句之前case
跳过每个非常规文件的名称。
使用 GNU find
:
find /usr/bin -maxdepth 1 -type f -name '*file*' -regex '.*/[a-z]*$'
这也进行了两级过滤。首先在必须匹配的基本名称上*file*
,然后在路径名的末尾(-regex
与完整路径名匹配)以确保那里只有小写字母。
答案4
ls /usr/bin | grep '\<[a-z][^\-]*file[a-z][^\-]*\>'