31

bashを使用して、インタプリタが文句を言わずにシェルスクリプトからディレクトリを除いて、フォルダ内のファイルの数を取得するにはどうすればよいですか?

友達の助けを借りて、私は試しました

$files=$(find ../ -maxdepth 1 -type f | sort -n)
$num=$("ls -l" | "grep ^-" | "wc -l")

これはコマンドラインから戻ります:

../1-prefix_blended_fused.jpg: No such file or directory
ls -l :  command not found
grep ^-: command not found
wc -l:   command not found

それぞれ。これらのコマンドはコマンドラインで機能しますが、bashスクリプトでは機能しません。

のようにフォーマットされた画像ファイルで満たされたファイルがある場合1-pano.jpg、ディレクトリ内のすべての画像を取得して、処理中の次の画像に追加する最大番号のファイルを取得します。

なぜ矛盾があるのですか?

4

10 に答える 10

43

引用符がエラーメッセージを引き起こしています。

ディレクトリ内のファイルの数を取得するには:

shopt -s nullglob
numfiles=(*)
numfiles=${#numfiles[@]}

これにより、配列が作成され、その要素の数に置き換えられます。これにはファイルとディレクトリが含まれますが、ドットファイルやその他のドット付きディレクトリは含まれませ...

nullglob空のディレクトリが1ではなく0のカウントを与えるように使用します。

代わりに使用するfind -type fか、ディレクトリをカウントして減算することができます。

# continuing from above
numdirs=(*/)
numdirs=${#numdirs[@]}
(( numfiles -= numdirs ))

「ディレクトリ内の最新(最新、最古、最古)のファイルを見つけるにはどうすればよいですか?」も参照してください。

実行ブロック内には、必要な数のスペースを含めることができます。彼らはしばしば読みやすさを助けます。唯一の欠点は、ファイルが少し大きくなり、最初の解析が(のみ)わずかに遅くなる可能性があることです。スペースが必要な場所がいくつかあり(たとえば、、、、の周り[、および比較で)、そうで[[ない]場所がいくつかあります(たとえば、割り当ての周り)。]]==

于 2012-06-21T04:21:12.633 に答える
19
ls -l | grep -v ^d | wc -l

1行。

于 2015-07-22T03:50:02.693 に答える
16

どうですか:

count=$(find .. -maxdepth 1 -type f|wc -l)
echo $count
let count=count+1 # Increase by one, for the next file number
echo $count

このソリューションは効率的ではないことに注意してください。コマンドのサブシェルを生成findwcますが、機能するはずです。

于 2012-06-21T05:37:37.427 に答える
3

file_num=$(ls -1 --file-type | grep -v '/$' | wc -l)

これはfindコマンドよりも少し軽量で、現在のディレクトリのすべてのファイルをカウントします。

于 2012-06-21T07:55:56.050 に答える
2

私が考えることができる最も簡単で信頼できる方法は、findコマンドを使用して信頼性の高いカウント可能な出力を作成することです。

findで出力された文字を数えるwc

find . -maxdepth 1 -type f -printf '.' | wc --char

または出力の文字列の長さfind

a=$(find . -maxdepth 1 -type f -printf '.')
echo ${#a}

または、find出力を使用して算術式を入力します。

echo $(($(find . -maxdepth 1 -type f -printf '+1')))
于 2019-08-25T13:06:59.540 に答える
1

引用符を取り除きます。シェルはそれらを1つのファイルのように扱っているため、「ls-l」を探しています。

于 2012-06-21T03:13:54.227 に答える
1

シンプルで効率的な方法:

#!/bin/bash
RES=$(find ${SOURCE} -type f | wc -l)
于 2014-09-11T15:37:03.813 に答える
0

qoutesを削除し、あなたは大丈夫になります

于 2012-06-21T03:17:14.730 に答える
0

受け入れられた回答の拡張(Dennis Wによる):このアプローチを試したとき、Bash4.4.5でサブディレクトリのないdirのカウントが正しくありませんでした。

問題は、デフォルトではnullglobがBashに設定されておらずnumdirs=(*/)、globパターンで1要素の配列を設定すること*/です。同様にnumfiles=(*)、空のフォルダに対して1つの要素があると思います。

shopt -s nullglobnullglobbingを無効に設定すると、問題が解決します。nullglobがBashでデフォルトで設定されない理由に関する優れた議論については、ここで答えを参照してください:nullglobがデフォルトではないのはなぜですか?

注:私は答えに直接コメントしたでしょうが、評判のポイントが不足しています。

于 2017-02-25T15:50:16.707 に答える
0

これが関数としてそれを行うことができる1つの方法です。注:この例を渡すことができます。dirsは(ディレクトリ数)、filesはファイル数、または「all」はディレクトリ内のすべてのものを数えます。私たちがそうすることを探していないので、ツリーをトラバースしません。

function get_counts_dir() {

    # -- handle inputs (e.g. get_counts_dir "files" /path/to/folder)
    [[ -z "${1,,}" ]] && type="files" || type="${1,,}"
    [[ -z "${2,,}" ]] && dir="$(pwd)" || dir="${2,,}"

    shopt -s nullglob
    PWD=$(pwd)
    cd ${dir}

    numfiles=(*)
    numfiles=${#numfiles[@]}
    numdirs=(*/)
    numdirs=${#numdirs[@]}

    # -- handle input types files/dirs/or both
    result=0
    case "${type,,}" in
        "files")
            result=$((( numfiles -= numdirs )))
        ;;
        "dirs")
            result=${numdirs}
        ;;
        *)  # -- returns all files/dirs
            result=${numfiles}
        ;;

    esac

    cd ${PWD}
    shopt -u nullglob

    # -- return result --
    [[ -z ${result} ]] && echo 0 || echo ${result}
}

関数の使用例:

folder="/home"
get_counts_dir "files" "${folder}"
get_counts_dir "dirs" "${folder}"
get_counts_dir "both" "${folder}"

次のようなものを印刷します:

2
4
6
于 2019-02-28T16:48:32.417 に答える