각 디렉토리의 디렉토리와 파일을 오름차순으로 정렬하고 데이터를 csv로 내보냅니다.

각 디렉토리의 디렉토리와 파일을 오름차순으로 정렬하고 데이터를 csv로 내보냅니다.

각 디렉터리에 300개가 넘는 텍스트 파일이 있는 30개의 디렉터리가 있습니다. 각 디렉터리의 모든 텍스트 파일은 동일한 명명 형식을 갖습니다.

regional_vol_GM1.txt
regional_vol_GM2.txt
regional_vol_GM*.txt 

디렉터리와 텍스트 파일을 순서대로 정렬하고 각 파일의 데이터를 csv 파일로 내보내고 싶습니다.

다음은 제가 쓴 스크립트입니다

for dir in * ; do


   paste -s -d ',' <(tail -q -n 1 "$dir"/t1/regional_vol*.txt ) >> data.csv

 done

내가 받고 있는 출력 csv 파일이 정렬되지 않았습니다. 디렉토리의 모든 파일을 오름차순으로 정렬하고 데이터를 csv로 내보내려면 어떻게 해야 합니까?

답변1

문제가 순서가 숫자가 아닌 어휘순인 경우 zsh다음을 사용하여 수행할 수 있습니다.

for dir in *(n/); do
  tail -q -n 1 "$dir"/t1/regional_vol*.txt(n) | paste -s -d ',' -
done > data.csv

glob n한정자는 정렬을 숫자로 만듭니다.

사용이 zsh옵션이 아니지만 GNU 옵션을 사용하는 경우 또 다른 접근 방식은 GNU 옵션을 ls사용하는 것입니다.ls-v버전유형:

eval "dirs=($(ls -v --quoting-style=shell-always))"
for dir in "${dirs[@]}"; do
  eval "files=($(
    ls -vd --quoting-style=shell-always -- "$dir"/t1/regional_vol*.txt))"
  tail -q -n 1 -- "${files[@]}" | paste -sd , -
done > data.csv

그래 그거야출력 구문 분석ls그리고사용eval같은 명령으로!

하지만 여기서는 와 같은 형식으로 ls출력 되기 때문에 안전합니다 .--quoting-style=shell-alwayseval

행 및 열 머리글을 추가하려면 다음을 수행합니다.

{
  eval "dirs=($(ls -v --quoting-style=shell-always))"
  headers_done=false
  for dir in "${dirs[@]}"; do
    (
      cd -- "$dir/t1" || exit
      eval "files=($(
        ls -vd --quoting-style=shell-always regional_vol*.txt))"
      if ! "$headers_done"; then
        printf DIR
        printf ',%s' "${files[@]}"
        printf '\n'
        headers_done=true
      fi
      printf %s, "$dir"
      tail -q -n 1 -- "${files[@]}" | paste -sd , -
    )
  done
} > data.csv

관련 정보