findを使用せずにスペースと特殊文字を含むファイル名を一覧表示する方法

findを使用せずにスペースと特殊文字を含むファイル名を一覧表示する方法

ファイル名にスペース、*、?、$、%などを含むディレクトリのファイルのリストを提供する必要があるスクリプトを作成しています。とにかく、たくさんの投稿を見ましたが、私に合った投稿が見つかりませんでした。 grepを使ってこれは可能ですか?

答え1

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

隠しファイルは報告しません。[[:space:]]マルチバイト間隔文字(例" "電磁四重)UTF-8)はシェルによって異なります(一部は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

スペースで区切られたリストです。はい、改行文字を含むファイル名があるため、2行あります。

ファイルを表示するより簡単な方法は、ファイル名を引用してクリーンなファイルのリストを取得する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

もちろん、通常*のように、全体ではなく一部のファイルを選択する必要があります。
したがって、一致するすべての文字を含むパターンを作成します?$*%
ただし、これらの文字のほとんどは「特殊」文字であるため、特定のコマンドに表示されるときに引用する必要があります。特に、*または?次の場合は$シェルによって拡張されるため、問題が発生する可能性があります。
must be quoted 次に、他のすべての文字を引用する簡単な方法は、次を使用すること$です。バックスラッシュが必ずしも必要でない場合、悪影響はなく、エスケープされた文字は引き続き機能します。このリストにスペース文字を追加する必要があります。しかし、新しい路線の追加は深刻な問題になった。文字クラスで改行文字を処理する最も簡単な方法はを使用することです。これには、改行文字、スペース、タブ、その他のスペース文字(em dashなど)が含まれます。
printf '%q' ?\$*%\?\$\*%
[[:space:]]

したがって、コマンドは次のようになります。

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

cleanおよびファイル名は必須normal_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

必要に応じて追加のケースを追加できます。

関連情報