如何在不使用 find 的情况下列出包含空格和特殊字符的文件名

如何在不使用 find 的情况下列出包含空格和特殊字符的文件名

我正在编写一个脚本,要求我提供目录中的文件列表,其文件名包含空格、*、?、$、% 等。我该怎么做,我看过很多帖子,但找不到任何适合我的东西。使用 grep 可以实现这一点吗?

答案1

printf '<%s>\n' *[[:space:]*?$%]*

它不会报告隐藏文件。是否[[:space:]]匹配多字节间距字符(如" "(电磁四元组)在 UTF-8 中)取决于您的 shell(有些还dash不能识别多字节字符)

例子:

$ touch sane 'a%b' $'with\nnewline' $'with space' $'with em-quad'
$ printf '<%s>\n' *[[:space:]*?$%]*
<a%b>
<with em-quad>
<with
newline>
<with space>

答案2

*使用不带引号的, 不使用 find生成文件的安全列表:

$ echo *

让我们有一些文件来测试:

$ mkdir test-dir; cd test-dir
$ touch clean normal_file 'a%b' 'has two spaces' '*' 'a*b' '?' 'a?b'
$ touch '$' 'a$b' '%' 'a%b' $'new\nline' $'em\u2001quad' 'normal_file'

echo *命令将生成上述文件:

? $ * % a?b a$b a*b a%b clean em quad has two spaces new
line normal_file

由空格分隔的列表,是的,有两行,因为有一个文件名称中包含换行符。

查看文件的一种更简单的方法是引用它们的名称printf '%q'并添加新行,就像printf '%q\n'我们得到一个干净的文件列表一样:

$ printf '%q\n' *
\?
\$
\*
%
a\?b
a\$b
a\*b
a%b
clean
$'em\342\200\201quad'
has\ two\ spaces
$'new\nline'
normal_file

当然,您需要选择一些文件,而不是全部,就像普通的 *.
因此,我们创建一个所有要匹配的字符的模式:?$*%
然而,大多数这些字符都是“特殊”的,当出现在某些命令中时需要引用。具体来说,如果*?跟随$,它们会被 shell 扩展,这可能会产生问题。
必须引用$.
然后,获取所有其他字符被引用的简单方法是使用printf '%q' ?\$*%.这将产生:\?\$\*%。如果不是严格需要反斜杠,则不会产生不良影响,转义字符仍然有效。
我们需要向该列表添加一些空白字符。但新线的加入成为一个严重的问题。在字符类中处理换行符的最简单方法是使用[[:space:]],它将包括换行符、空格、制表符和一些其他空格字符(如长破折号)。

因此,命令变为:

$ printf '%q\n' *[\?\$\*%[:space:]]*
\?
\$
\*
%
a\?b
a\$b
a\*b
a%b
$'em\342\200\201quad'
has\ two\ spaces
$'new\nline'

请注意,cleannormal_file文件名未按要求列出。

答案3

grep -E应该做你需要的。请注意,某些字符需要使用反斜杠进行转义,因此如果您添加更多字符并且结果不是您所期望的,请对其进行转义并重试。请注意,这|是一个or...

$ ls | grep -E '\s|\*|\?|\$|%'
all this.txt
all?this.txt
all*this.txt
all%this.txt
all th*s.txt
all$.txt

答案4

这非常简单,并且从 1979 年起就已经可以在 Bourne Shell 中使用:

for i in *
do
    case "$i" in
        *\ *) echo blank $i;;
        *\?*) echo qmark $i;;
    esac
done

一行:

for i in *; do
    case $i in
        *\ *|*\?*|*\**|*\$*|*%* ) echo "Special character $i"; ;;
        * ) echo "normal file $i"; ;;
    esac
done

如果您愿意,可以添加更多案例...

相关内容