![파일 정보를 배열에 저장하는 방법은 무엇입니까?](https://rvso.com/image/1087142/%ED%8C%8C%EC%9D%BC%20%EC%A0%95%EB%B3%B4%EB%A5%BC%20%EB%B0%B0%EC%97%B4%EC%97%90%20%EC%A0%80%EC%9E%A5%ED%95%98%EB%8A%94%20%EB%B0%A9%EB%B2%95%EC%9D%80%20%EB%AC%B4%EC%97%87%EC%9E%85%EB%8B%88%EA%B9%8C%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
)를 구분하고 그 뒤에 를 추가했습니다 /
. 따라서 .
에서 필드 구분 기호로 사용할 수 있습니다 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