Как хранить информацию файла в массив?

С этой частью сценария я могу получить необходимую информацию о файлах в моем каталоге (и подкаталоги). Единственной информацией, в которой я нуждаюсь, является расширение и размер файла.

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}"

Это - только часть сценария. Таким образом, мой вопрос: Как я могу поместить этот informarion в массив? Я подразумеваю, что хочу, чтобы массив с элементами был похож на это:

 c/123 /12 h/90 /0 txt/0

где c, h и txt являются расширением файла и 123, 12 и 0 размеры файла. Таким образом, в последнее время я могу отдельно работать с размерами и расширениями
Я надеюсь, я аккуратно подавил свой вопрос. Извините за ошибки.:)

1
задан 28 March 2016 в 00:52

2 ответа

Во-первых, не делать for file in $(find …). Это очень хрупко.

Теперь, можно упростить код немного получением, находят для печати имен файлов и размеров вместе, с помощью -printf:

find . -type f -printf '%s.%f/'

Затем можно использовать awk обработать этот вывод для получения кумулятивных размеров следовательно. Обратите внимание, что я использовал . разделить имя файла (%f) от размера (%s), и я добавил a / после этого. Следовательно, я могу использовать . как разделитель полей в awk. И так как единственные символы, не позволенные в именах файлов, / и NUL ASCII, я могу безопасно использовать / как разделитель записей.

Так:

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
1
ответ дан 7 December 2019 в 13:47

Вот короткий сценарий удара, что делает задание:

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
1
ответ дан 7 December 2019 в 13:47

Другие вопросы по тегам:

Похожие вопросы: