각 디렉터리에 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-always
eval
행 및 열 머리글을 추가하려면 다음을 수행합니다.
{
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