Linuxの下でどのようにBashであるモードのファイル名が存在するかを判断します

4946 ワード

問:LinuxではどのようにBashで何らかのパターンのファイル名があるかどうかを判断しますか?
たとえば、スクリプトで*_があるかどうかを判断します.codec.* 形式のファイル名、または*があります.gif形式のファイル名.
 
回答:
方法1:
[ "$(ls *.gif 2>/dev/null)"] && echo "*.gif exists"|| echo "*.gif not exists"
方法2:
exists_pattern_files(){     [ -e "$1"] }
exists_pattern_files *.gif && echo "*.gif exists"|| echo "*.gif not exists"
 
探索プロセス:
 
test-e fileまたは[-e file]では単一の確定名のファイルしか判断できませんが、ワイルドカードモードで指定されたファイル名であれば、この方法は効果的ではありません.
次の3つのケースを考慮する必要があります.
(1)このモードに一致するファイルがありません.
(2)このモードに一致するファイルがちょうど1つあります.
(3)このモードに一致するファイルが1つ以上ある.
 
以下*.gifモードでテスト:
(1)このモードに一致するファイルがありません.
[root@liunx0918 tmp0]# ls *.gif ls: *.gif:そのファイルやディレクトリはありません[root@liunx0918 tmp0]# [ -e *.gif ] && echo "*.gif exists"|| echo "*.gif not exists" *.gif not exists [root@liunx0918 tmp0]#
(2)このモードに一致するファイルがちょうど1つあります.
[root@liunx0918 tmp0]# touch 1.gif [root@liunx0918 tmp0]# ls *.gif 1.gif [root@liunx0918 tmp0]# [ -e *.gif ] && echo "*.gif exists"|| echo "*.gif not exists" *.gif exists [root@liunx0918 tmp0]#
(3)このモードに一致するファイルが1つ以上ある.
[root@liunx0918 tmp0]# touch 2.gif [root@liunx0918 tmp0]# ls *.gif 1.gif  2.gif [root@liunx0918 tmp0]# [ -e *.gif ] && echo "*.gif exists"|| echo "*.gif not exists"-bash: [: 1.gif: binary operator expected *.gif not exists [root@liunx0918 tmp0]#
 
前の2つの状況は、3つ目の状況のスクリプトが間違っていると判断することができます.誰が一致するファイルが1つ以上にならないことを保証することができますか?
 
まず,lsコマンドでこのモードファイルの出力を先にリストして判断できることを考える.次のようになります.
(1)このモードに一致するファイルがありません.
[root@liunx0918 tmp1]# ls *.gif ls: *.gif:そのファイルやディレクトリはありません[root@liunx0918 tmp1]# [ "$(ls *.gif)"] && echo "*.gif exists"|| echo "*.gif not exists"ls: *.gif:そのファイルやディレクトリはありません*.gif not exists [root@liunx0918 tmp1]#
上记の赤いマークの内容に注意して、実はシナリオの中でこの情报を见たくなくて、この情报は标准の间违って出力したので、以下の方法で
[root@liunx0918 tmp1]# [ "$(ls *.gif 2>/dev/null)"] && echo "*.gif exists"|| echo "*.gif not exists" *.gif not exists [root@liunx0918 tmp1]#
(2)このモードに一致するファイルがちょうど1つあります.
[root@liunx0918 tmp1]# touch 1.gif [root@liunx0918 tmp1]# ls *.gif 1.gif [root@liunx0918 tmp1]# [ "$(ls *.gif 2>/dev/null)"] && echo "*.gif exists"|| echo "*.gif not exists" *.gif exists [root@liunx0918 tmp1]#
(3)このモードに一致するファイルが1つ以上ある.
[root@liunx0918 tmp1]# touch 2.gif [root@liunx0918 tmp1]# ls *.gif 1.gif  2.gif [root@liunx0918 tmp1]# [ "$(ls *.gif 2>/dev/null)"] && echo "*.gif exists"|| echo "*.gif not exists" *.gif exists [root@liunx0918 tmp1]#
 
突然ひらめいて、lsでファイルを列挙することで行うことができる以上、実はBash自体がファイル名ワイルドカード展開をサポートしているので、簡単な関数を書いてみてはいかがでしょうか.
exists_pattern_files(){
    [ -e "$1" ]
}
 
[root@liunx0918 tmp2]# exists_pattern_files(){ > [ -e "$1"] > }
ファイル名モードをパラメータとしてこの関数(引用符なし)に渡すと、Bashは自動的にファイルモードを展開し、一致するファイルが何個あるかはパラメータとして渡され、モード自体はパラメータとして関数に渡されません.
一致するファイル名がない場合は、モード自体を関数に渡します.この関数の実装部分はかなり簡単で、最初のパラメータで指定したファイルを判断するだけで、念のため二重引用符をつけます.
(1)このモードに一致するファイルがありません.[root@liunx0918 tmp2]# ls *.gif ls: *.gif:そのファイルやディレクトリはありません[root@liunx0918 tmp2]# exists_pattern_files *.gif && echo "*.gif exists"|| echo "*.gif not exists" *.gif not exists
(2)このモードに一致するファイルがちょうど1つあります.[root@liunx0918 tmp2]# touch 1.gif [root@liunx0918 tmp2]# ls *.gif 1.gif [root@liunx0918 tmp2]# exists_pattern_files *.gif && echo "*.gif exists"|| echo "*.gif not exists" *.gif exists
(3)このモードに一致するファイルが1つ以上ある.[root@liunx0918 tmp2]# touch 2.gif [root@liunx0918 tmp2]# ls *.gif 1.gif  2.gif [root@liunx0918 tmp2]# exists_pattern_files *.gif && echo "*.gif exists"|| echo "*.gif not exists" *.gif exists [root@liunx0918 tmp2]#
 
このリンク:http://codingstandards.iteye.com/blog/1183303

 
次に、必要なスクリプトの内容を貼ります.
サブディレクトリに*_が含まれている場合は、現在のディレクトリの下の各サブディレクトリを判断します.codec.*形式のファイルは、指定したアクションを実行します.
 
実装1:
for d in *
do
        FILES=$(ls $d/*_codec.* 2>/dev/null)
        if [ "$FILES" ]; then
                #echo "$d" "[$FILES]"
                (cd $d; make msg)
        fi
done

 
実装2:
exists_pattern_files(){
    [ -e "$1" ]
}

for d in *
do
        if exists_pattern_files $d/*_codec.*; then
                #echo "$d" "[$FILES]"
                (cd $d; make msg)
        fi
done