![ファイル情報を配列に保存するにはどうすればいいですか?](https://rvso.com/image/1087142/%E3%83%95%E3%82%A1%E3%82%A4%E3%83%AB%E6%83%85%E5%A0%B1%E3%82%92%E9%85%8D%E5%88%97%E3%81%AB%E4%BF%9D%E5%AD%98%E3%81%99%E3%82%8B%E3%81%AB%E3%81%AF%E3%81%A9%E3%81%86%E3%81%99%E3%82%8C%E3%81%B0%E3%81%84%E3%81%84%E3%81%A7%E3%81%99%E3%81%8B%3F.png)
スクリプトのこの部分を使用すると、ディレクトリ (およびサブディレクトリ) 内のファイルに関する必要な情報を取得できます。必要な情報は、ファイルの拡張子とサイズだけです。
for file in `find . -type f`; do
size=$(stat -c '%s' ${file})
file=$(echo "${file}" | awk -F/ '{print $NF}')
ext=$(echo "${file}" | grep '..*\.' | awk -F. '{print $NF}' | grep '[A-Za-z0-9]')
if [ -z ${ext} ]; then
echo "NOTE: no extention"
else
EXTS="${EXTS}${ext}${newLine}"
これはスクリプトの一部にすぎません。質問は、この情報を配列に入れるにはどうしたらよいかということです。つまり、次のような要素を持つ配列が欲しいのです。
c/123 /12 h/90 /0 txt/0
ここで、c、h、txt はファイル拡張子、123、12、0 はファイル サイズです。最近はサイズと拡張子を別々に扱えるようになりました。
質問をきちんとまとめられたと思います。間違いがあったらごめんなさい。:)
答え1
初め、しないでくださいfor file in $(find …)
それはとても壊れやすいです。
ここで、次のようにして、find でファイル名とサイズを一緒に印刷することで、コードを少し簡略化できます-printf
。
find . -type f -printf '%s.%f/'
次に、 を使用しawk
てこの出力を処理し、拡張子ごとの累積サイズを取得できます。.
ファイル名 ( %f
) とサイズ ( %s
) を区切るために を使用し、その後に を追加したことに注意してください。したがって、でフィールド区切り文字として/
を使用できます。また、ファイル名で許可されていない文字はと ASCII NUL のみであるため、 をレコード区切り文字として安全に使用できます。.
awk
/
/
それで:
awk -F. -v RS=/ 'NF > 2 {size[$NF] += $1; next}
{size["/"] += $1}
END {for (i in size) {print i,"/",size[i]}'
/
ここでは、拡張子がない場合にインデックスとして使用しています。
組み合わせ:
$ find . -type f -printf '%s.%f/' | awk -F. -v RS=/ 'NF > 2 {size[$NF] += $1; next}
{size["/"] += $1}
END {for (i in size) {printf "%s/%d\n", i, size[i]}}'
h/780
md/2509
tex/23961
c/13557
//5109
txt/2349291
sh/1166
py/12248
拡張子にスペースが含まれていない場合は、次のようにします。
my_array=( $(find . -type f -printf '%s.%f/' | awk -F. -v RS=/ 'NF > 2 {size[$NF] += $1; next} {size["/"] += $1} END {for (i in size) {printf "%s/%d\n", i, size[i]}}') )
または、プロセス置換を使用して、次の各エントリを読み取ることもできます。
my_arr=()
while IFS='' read -r entry
do
my_arr+=( "$entry" )
done < <(find . -type f -printf '%s.%f/' | awk -F. -v RS=/ 'NF > 2 {size[$NF] += $1; next} {size["/"] += $1} END {for (i in size) {printf "%s/%d\n", i, size[i]}}')
従来通り:
$ printf "%s\n" "${my_arr[@]}"
h/780
md/2509
tex/23961
c/13557
//5109
txt/2349291
sh/1166
py/12248
答え2
以下は、この作業を実行する短い bash スクリプトです。
i=0
while read -r -d $'\0' file
do
size=$(stat -c '%s' ${file})
ext=`basename $file | sed -re "s/^[^.]+.*\.//"`
if [ -z "$ext" ] || [ "$ext" = "`basename $file`" ] ; then
echo "NOTE: no extention ($file)"
else
extensions[$i]="$ext"
sizes[$((i++))]=$size
fi
done < <(find . -type f -print0)
for (( j=0 ; j<i; j++ )) do
echo index: $j / extension: ${extensions[$j]} / size: ${sizes[$j]}
done