파일 정보를 배열에 저장하는 방법은 무엇입니까?

파일 정보를 배열에 저장하는 방법은 무엇입니까?

스크립트의 이 부분을 사용하면 내 디렉터리(및 하위 디렉터리)에 있는 파일에 대해 필요한 정보를 얻을 수 있습니다. 필요한 유일한 정보는 파일의 확장자와 크기입니다.

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)를 구분하고 그 뒤에 를 추가했습니다 /. 따라서 .에서 필드 구분 기호로 사용할 수 있습니다 awk. 그리고 파일 이름에 허용되지 않는 유일한 문자는 /ASCII NUL이므로 /레코드 구분 기호로 안전하게 사용할 수 있습니다.

그래서:

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

관련 정보