現在の作業ディレクトリで、文字「f」を含むすべてのファイル名を取得するために、次のコードを書きました。
for i in *
do
echo $i
if [ $i = "*f*" ]
then
echo "no"
else
echo "yes"
fi
done
ディレクトリ内のすべてのファイルに「f」が含まれているかどうかに関係なく、「yes」が印刷されます。助けてください。
答え1
[ $i = "*f*" ]
変数に保存されているファイル名をi
スペースに基づいて別々の単語に分割し、各単語をワイルドカードパターンとして解釈し、一致する場合は展開し、結果の単語リストを次のように解析します[ … ]
。この面倒な作業を避けるために、代わりにファイル名を使用してください。変数拡張の周囲に二重引用符を追加する。
[ "$i" = "*f*" ]
変数のファイル名がi
3文字の名前であるかどうかをテストします*f*
。この名前のファイルが存在しない場合は、すべてのファイルがelseブランチをトリガーしてyes
印刷されます。
ksh、bash、またはzshでは、二重角括弧構成を使用して、文字列がワイルドカードパターンと一致するかどうかをテストできます。パターンのワイルドカード文字を引用符なしで残します。
if [[ "$i" = *f* ]]; then …
通常のshには二重括弧構文はありません。文字列がパターンと一致するかどうかをテストするには、case
コンストラクタを使用できます。
case "$i" in
*f*) echo "no";;
*) echo "yes";;
esac
答え2
f
文字を含むファイルのみを表示したいので、continue
組み込みが必要です。例えば
for f in *; do if [[ $f != *f* ]]; then continue; else printf '%s\n' "$f yes"; fi; done
すべてのファイルとそのファイルを表示するには、次の手順を実行する必要がありますyes
。no
for f in *; do if [[ $f = *f* ]]; then printf '%s\n' "$f yes"; else printf '%s\n' "$f no"; fi; done
上記の方法はディレクトリにも適用されます。したがって、ディレクトリを除外するには、! -d $f
次の例を使用できます。
for f in *; do if [[ $f = *f* && ! -d $f ]]; then printf '%s\n' "$f yes"; else printf '%s\n' "$f no"; fi; done
答え3
test
("test"組み込みコマンドと同義語)コマンドは[
パターンの使用を許可しません。
STRING1 = STRING2
True if the strings are equal.
したがって、文字列を文字で比較してファイルが存在しないことを確認します。*f*
yes
ディレクトリの名前(したがって、名前が一致しない場合、リバースマッチスクリプトはエコーされます)。 -buitinの
代わりに自由に使用することもできます。test
/bin/test
バッシュキーワード [[
When the `==' and `!=' operators are used, the string to the right of
the operator is used as a pattern and pattern matching is performed.
When the `=~' operator is used, the string to the right of the operator
is matched as a regular expression.
次の両方を使用できます。
[[ "$i" == *f* ]]
[[ "$i" =~ f ]]
f
ただし、名前にファイル名を含む現在のディレクトリのファイルのみを印刷したい場合は、次のようにすればecho
十分です。
echo *f*
答え4
これは繰り返し練習ですか?そうでない場合は、 find を使用する方が簡単になります。
search=$(find /path/to/dir -type f -name *f*)
echo $search