如何将文件信息存储到数组中?

如何将文件信息存储到数组中?

通过这部分脚本,我可以获得有关目录(和子目录)中文件的必要信息。我唯一需要的信息是文件的扩展名和大小。

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

相关内容