有人可以解释一下为什么这个正则表达式在 grep 中不起作用?
ls -la ./ | grep -E '^d.*\<\..*\>$'
在我(错误的)看来,这必须向我显示名称以“.”开头的目录行,因为:
- ^d -> 保留以字符“d”开头的行
- .* -> 无或任意字符组合
- $ -> 行尾
问题是我不明白这一点:
- \< -> 单词开头
- 。 -> 转义点
- .* -> 无或任意字符组合
- > -> 单词结尾
所以我认为正则表达式的这一部分保留了包含以点开头并以字符组合结尾的单词的行。
使用此“ls -la”,带有 grep 的正则表达式不会显示任何结果:
[arch dirtest]$ ls -la
total 52
drwxr-xr-x 6 siv users 4096 10 nov 00.41 .
drwx------ 59 siv users 4096 9 nov 23.15 ..
drwxr-xr-x 2 siv users 4096 10 nov 00.41 .test
drwxr-xr-x 2 siv users 4096 10 nov 00.41 test1
drwxr-xr-x 2 siv users 4096 10 nov 00.41 test2
答案1
您的正则表达式不起作用,因为.
不是单词字符。 Grep 仅将a-z
、A-Z
、0-9
和_
视为单词字符。
无论如何,这确实不是正确的做法。首先,解析ls
是非常脆弱几乎从来都不是一个好主意。以下是列出名称以 开头的目录的一些其他方法.
:
find . -type d -name '.*'
或者,如果您不希望它进入子目录(并且如果您有 GNU find
,这是 Linux 上的默认设置):
find . -maxdepth 1 -type d -name '.*'
或者,您可以只使用echo
shell glob:
echo .*
这也将显示文件。为了避免这种情况,请使用如下循环:
for i in .*; do [ -d "$i" ] && printf '%s\n' "$i"; done
答案2
您似乎在之后省略了设备方法-D
?
ls -la ./ | grep -D skip '^d.*\<\..*\>$'
不管怎样......问题是你正在寻找一个词首边界 ,\<
后跟一个文字点 ,\.
。这总是会失败,因为点不被视为单词字符。引用info grep
GNU grep 的内容:
`-w'
`--word-regexp'
... Word-constituent characters are letters, digits, and the underscore.
\<
用空格替换似乎工作可靠。然而,我同意 user:terdon 的观点,即解析输出ls -la
是脆弱的,并且有更好的方法来获得你想要的东西。