2016-04-11 26 views
2

現在、いくつかのbashスクリプトを学習しており、特定のディレクトリ内のすべてのファイルをリストし、ファイルまたはディレクトリであるかどうかを問う問題があります。私が抱えている問題は、現在のディレクトリだけを取得するか、またはディレクトリを指定すると、それがディレクトリであると言うことになります。/home/user/shell_scriptsが返すshell_sciptsは、その中に含まれるファイルではなくディレクトリです。 これは私がこれまで持っているものです。シェル指定されたディレクトリ内のファイルとそのファイルまたはディレクトリをリストするスクリプト

dir=$dir 
for file in $dir; do 
    if [[ -d $file ]]; then 
     echo "$file is a directory" 
    if [[ -f $file ]]; then 
     echo "$file is a regular file" 
    fi 
done 

答えて

2

あなたのラインと

$(ls $dir) 

を置き換える:

for file in $dir; do 

は、単一のディレクトリ文字列にだけ$dirを展開します。あなたがする必要があるのは、ディレクトリ内のファイルのリストに展開することです。

for file in "${dir}/"* ; do 

これは、現在のディレクトリの名前のみのリストに"${dir}/"*セクションを展開します:あなたはこの次を使用して行うことができます。 Biffenが指摘しているように、ファイルリストに空白が含まれていれば、部分ファイル名の分割がfileになることはありません。

dirのディレクトリに再帰したい場合は、findを使用するとよいでしょう。単純に使用します。

for file in $(find ${dir}); do 

なお、シンプルな中、この意志彼らにスペースを持つないハンドルファイルまたはディレクトリ。このため、私はループを落として、一度に出力を生成するように誘惑されます。これは、あなたが望むものとは多少異なるかもしれませんが、特に大量のファイルでは、読みやすく、より効率的です。

find ${dir} -maxdepth 1 -type d 

をし、ファイルを一覧表示する:たとえば、すべてのディレクトリを一覧表示するには

find ${dir} -maxdepth 1 -type f 

あなたは以下のディレクトリに反復処理したい場合は、その後、-maxdepth 1

+0

非常に多くのファイル(コマンドラインが長すぎます)があると、これが壊れる可能性があります。 – user1934428

+0

はい、私はこのアプローチを非常に多数のファイル(> 10^5)に使用していましたが、問題はありませんでした。私は 'for' /' do'/'done'アプローチを取り除き、できるだけ効率的な' ls'や 'find'コマンドを直接使用したいと思っています。 OPの質問。それに応じて更新します。 –

+0

空白やその他の特殊文字を含むファイル名ではうまく動作しません。 – Biffen

0
for file in $(ls $dir) 
do 
    [ -f $file ] && echo "$file is File" 
    [ -d $file ] && echo "$file is Directory" 
done 

または

`ls $` 
+0

空白やその他の特殊文字を含むファイル名ではうまく動作しません。 '' ls $ 'は何をやろうとしているのですか? – Biffen

1
ls -F ~ | \ 
sed 's#.*/$#/& is a Directory#;t quit;s#.*#/& is a File#;:quit;s/[*/=>@|]//' 

削除-F "classify"スイッチは、ファイルがディレクトリの場合は "/"を追加します。 sedコードは、目的のメッセージを出力してから、接尾辞を削除します。

+1

名前に改行を含むファイルでは機能しません。 – Biffen

+1

ありがとう@Biffen、それは恐ろしいです、改行でファイル名は_thing_ですか?ちょうどそれらを見上げた。ちょうど1つ作った。上記の** sed **コードをテストしました。これは失敗しました。しかし、誰がそこに改行を望んでいたとしても、このことの歴史は何ですか?私は「方法」を取得し、「理由」を求めます... – agc

+1

「どうしてですか?」以外の理由では、本当に答えられません。 ;) – Biffen

2

これはglobbingのために良い使用です:

for file in "$dir/"* 
do 
    [[ -d "$file" ]] && echo "$file is a directory" 
    [[ -f "$file" ]] && echo "$file is a regular file" 
done 

これは$dir内のファイルは、スペース、アスタリスクとさえ改行として自分の名前に特殊文字を、持っている場合でも動作します。

変数は引用符で囲む必要があります("$file")。しかし、*は、を引用することはできません。そして、何もしないので($dirに特殊文字が含まれている場合はブレークを除く)dir=$dirを削除しました。

関連する問題