特定のファイルタイプ/拡張子がディレクトリに存在するかどうかを確認します


84

特定の拡張子のファイルがbashを使用してディレクトリに存在するかどうかをどのように判断しますか?

何かのようなもの

if [ -e *.flac ]; then 
echo true; 
fi 

回答:


104
#!/bin/bash

count=`ls -1 *.flac 2>/dev/null | wc -l`
if [ $count != 0 ]
then 
echo true
fi 

9
トーマスさん、単に反対票を投じるのではなく、質問にもっと良い解決策を追加してみませんか。
JeremyWeir 2015年

8
また、トーマス、それを使用しない理由のあなたの例は使用ls -lしています、私の答えは使用しますls -1
JeremyWeir 2015年

10
そして、この答えは出力を解析するのではなく、出力された行を数えるだけです。ファイル名に奇妙な文字が含まれていても、ファイルls -1ごとに1行を出力することはほぼ確実です
JeremyWeir 2015年

2
行数のカウント解析中です。また、ファイルに含まれている場合は誤った番号が返されます\n(はい、ファイル名で有効です)。
marcelm

1
それでは、行数を無駄にするために、ファイルの名前にどのような魔法の文字が含まれている必要があるのでしょうか。
ヨーマン

27
#/bin/bash

myarray=(`find ./ -maxdepth 1 -name "*.py"`)
if [ ${#myarray[@]} -gt 0 ]; then 
    echo true 
else 
    echo false
fi

5
ファイルを見つけたら実際に何かを行うことができるので、これは素晴らしいです。
ephsmith 2012

括弧内のfindを実行しているサブシェルをラップしてmyarrayを配列変数にするための+1。それ以外の場合、find${#myarray[@]}が1に等しい結果を返さない場合
shaffooo 2017

ls -1 *.py検索の代わりに使用することで簡略化することもできます
JrBenito 2010

いずれかのファイルの名前にスペースが含まれている場合、これは1つのインスタンスを2つとしてカウントします。
ジョングリフィス

16

これはls(1)を使用し、flacファイルが存在しない場合、lsはエラーを報告し、スクリプトは終了します。それ以外の場合、スクリプトは続行され、ファイルが処理される可能性があります

#! /bin/sh
ls *.flac  >/dev/null || exit
## Do something with flac files here

4
さらに沈黙させるには、2>&1もリダイレクトします。
ジャスパー2014

6
ifバージョン:if ls *.flac >/dev/null 2>&1; then ... fi;
Josiah Yoder 2015


4

あなたはあなたがあなたのif声明にどの旗を投げるか、そしてそれがあなたが望む結果にどのように関係しているかに注意を払う必要があります。

通常のファイルのみをチェックし、他のタイプのファイルシステムエントリはチェックしない場合は、コードスケルトンを次のように変更する必要があります。

if [ -f file ]; then
echo true;
fi

を使用すると、-fif通常のファイルに制限されますが、-eより拡張性が高く、すべてのタイプのファイルシステムエントリに一致します。もちろん-d、ディレクトリなどの他のオプションもあります。適切なリストについては、http://tldp.org/LDP/abs/html/fto.htmlを参照してください。

@mswで指摘されているように、複数の引数を指定しようとすると、test(つまり[)がチョークします。これは、のglobが*.flac複数のファイルを返した場合に発生する可能性があります。その場合ifは、次のようなループでテストをラップしてみてください。

for file in ./*.pdf
do
    if [ -f "${file}" ]; then
    echo 'true';
    break
    fi
done

このようにbreakして、必要なファイル拡張子の最初のインスタンスで、スクリプトの残りの部分を続行できます。


1
ただし、test(aka [)は、パターンが複数のファイルに展開される場合に文句を言います:「二項演算子が必要です」または「引数が多すぎます」
msw 2010年

1
@ msw-ありがとう、私もその問題について考えていませんでした。私はそれを考慮に入れるために私の答えを修正しようとしました。
dtlussier 2010年

"$file"ファイル名にスペースやアスタリスクなどの不適切な文字が含まれている可能性があるため、変数を引用符で囲むか、を使用する必要があります。
Roman Cheplyaka 2010年

3
#!/bin/bash
files=$(ls /home/somedir/*.flac 2> /dev/null | wc -l)
if [ "$files" != "0" ]
then
echo "Some files exists."
else
echo "No files with that extension."
fi


3

-fを使用して、特定のタイプのファイルが存在するかどうかを確認できます。

#!/bin/bash

if [ -f *.flac ] ; then
   echo true
fi 

これは機能しますが、あなたはリードを埋めています-それが機能する理由は、[(より一般的なものとは対照的に[[)シングルブレースがグロブを防止しないためです。
エイドリアンペトレスク

2
   shopt -s nullglob
   set -- $(echo *.ext)
    if [ "${#}" -gt 0 ];then
      echo "got file"
    fi

これは間違っています。まず、おそらく-ge代わりに意味し-gtます。そうしないと、コードが単一のファイルを検出しないためです。次に、パターンに一致するファイルがない場合、準拠するシェルは文字列を*.extそのままにしておくため、1つの「結果」が得られます。
Roman Cheplyaka 2010年

$#は、単一ファイルの場合は1、ファイルがない場合は0です。
フレイザー2015年

1

bashのみ:

any_with_ext () ( 
    ext="$1"
    any=false
    shopt -s nullglob
    for f in *."$ext"; do
        any=true
        break
    done
    echo $any 
)

if $( any_with_ext flac ); then
    echo "have some flac"
else 
    echo "dir is flac-free"
fi

サブシェルが使用されていることを確認するために、中括弧の代わりに括弧を使用します(現在のnullglob設定を壊したくない)。


1

これは、外部コマンドを使用せず(つまり、no ls)、代わりにシェル関数を使用するソリューションです。bashでテスト済み:

shopt -s nullglob
function have_any() {
    [ $# -gt 0 ]
}

if have_any ./*.flac; then
    echo true
fi

この関数have_anyは、$#を使用して引数をカウントし[ $# -gt 0 ]、少なくとも1つの引数があるかどうかをテストします。の呼び出し./*.flacだけでなくの使用は、のような名前のファイルによって引き起こされる問題を回避することです。*.flachave_any--help


1

完了するには、zshを使用します。

if [[ -n *.flac(#qN) ]]; then
  echo true
fi

これは、zshマニュアルの「条件式」セクションの最後にリストされています。以来[[無効のファイル名展開、我々は使用してファイル名の生成を強制する必要があり(#q)、その後、グロブ文字列の最後にNフラグ(NULL_GLOB一致はありませんオプション)の場合には、空のように生成された文字列を強制的に。


1

これはかなり簡単な解決策です:

if [ "$(ls -A | grep -i \\.flac\$)" ]; then echo true; fi

ご覧のとおり、これは1行のコードですが、十分に機能します。これは、bashと、dashのようなposix準拠のシェルの両方で機能するはずです。また、大文字と小文字は区別されず、どのタイプのファイル(通常、シンボリックリンク、ディレクトリなど)が存在するかは関係ありません。これは、シンボリックリンクなどがある場合に役立ちます。


ls -ARは再帰検索を行うので、私はこれが好きです。解凍後にzipアーカイブの内容を検索するのに適しています。
ジャスティンクレス

0

私はこれを試しました:

if [ -f *.html ]; then
    echo "html files exist"
else
    echo "html files dont exist"
fi

このコードを他のファイルには問題なく使用しましたが、htmlファイルにはエラーが発生しました

[: too many arguments

次に、@ JeremyWeirのカウントソリューションを試しました。

ループでこれを行う場合は、カウントをリセットする必要があることに注意してください。

count=$((0))

0

これは、そこにあるあらゆるボーンのようなシェルで機能するはずです。

if [ "$(find . -maxdepth 1 -type f | grep -i '.*\.flac$')" ]; then
    echo true
fi

これはGNUでも機能しますがfind、他の実装と互換性がある場合はIDK find

if [ "$(find . -maxdepth 1 -type f -iname \*.flac)" ]; then
    echo true
fi
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.