대규모 디렉토리에서 동시에 1000개의 파일을 효율적으로 결합하고 삭제합니다.

대규모 디렉토리에서 동시에 1000개의 파일을 효율적으로 결합하고 삭제합니다.

를 통해 이 작업을 수행할 수 있다는 것을 알고 있습니다 cat file [file] [[file] ...] > joined-file. 그 안에 수십만 개의 파일이 있는 디렉토리가 있습니다. 여러 그룹(1000개)의 파일을 하나의 파일로 연결하고 싶습니다. 아주 작은 파일 세트가 있습니다. 다른 서비스가 모든 파일 이름을 쉽게 읽고 메모리에 저장하여 작업할 수 있도록 이름과 순서에 관계없이 1000개의 파일을 연결하고 싶습니다.

내가 시도한 것은 다음과 같습니다.

for i in /var/abc/*.csv; do "$i" > file1.csv; rm -rf "$i"; done

그러나 다른 변수의 개수를 추적하십시오. 효과적인 방법은 무엇입니까? 이렇게 하면 1000개의 파일을 직접 연결하여 이동할 수 없습니다.

왜 1000입니까? 디렉터리에 수십만 개의 파일이 포함되어 있기 때문입니다. 하나의 출력 파일 크기가 제한을 초과하지 않도록 각 파일의 크기를 1-4KB로 설정했습니다. 나는 당신의 대답을 따르려고 노력했습니다.

cd /var/abc 
for file in $(ls -p | grep -v / | tail -1000); do cat "$file" >>"/var/abcd/xigzag"$tick".csv" && rm -rf "$file"; done

답변1

루프가 필요하지 않으며 cat모든 파일을 읽도록 지시할 수 있습니다.

cat /var/abc/*.csv > file1.csv && rm /var/abc/*.csv

파일이 너무 많지 않은 한(그러나 한계는 엄청납니다).

&&파일이 성공적으로 "복사"된 경우에만 삭제되도록 하기 위해 두 명령 사이에 사용됩니다 .

그러나 몇 가지 주의 사항이 있습니다.

  • 연결하려는 원본 파일과 동일한 폴더에서는 이 명령을 실행할 수 없습니다. 그렇지 않으면 rm집합이 삭제되고 모든 것을 잃게 됩니다.
  • cat의 시작과 매개변수 확장 사이에 새 CSV 파일이 나타나면 rm해당 파일은 삭제되고 복사되지 않습니다.
  • 가입 후 CSV 파일이 수정되면 해당 수정 사항이 손실됩니다.

출력 파일을 생성하기 전에 파일 목록을 저장하면 처음 두 가지 주의 사항을 완화할 수 있습니다.

set -- /var/abc/*.csv
cat -- "$@" > file1.csv && rm -- "$@"

파일을 복사한 후에도 파일에 대한 변경 사항은 여전히 ​​손실됩니다.

한 번에 1000개의 파일(1000개의 원본 CSV마다 하나의 CSV가 생성됨)과 원하는 수의 파일을 연결하려면 대상 디렉터리에서 다음 단계를 수행하면 됩니다.

find /var/abc -maxdepth 1 -type f -name \*.csv | split -d -l 1000 - csvlists
for file in csvlists*; do cat $(cat $file) > concat${file##csvlists}.csv && rm $(cat $file); done

/var/abc그러면 이름이 지정된 모든 파일을 찾고 *.csv( , ...)로 시작하는 파일에서 한 번에 1000개의 파일을 나열합니다. 그런 다음 각 파일 목록을 반복하고 나열된 CSV 파일을 이름이 등인 파일로 연결하여 목록과 일치시킵니다. 각 파일 세트가 복사된 후 원본 파일은 삭제됩니다.csvlistscsvlists00csvlists01forconcat00.csv

이 버전에서는 CSV 파일 이름에 공백, 줄 바꿈 등이 포함되어 있지 않다고 가정합니다.

답변2

귀하의 명령은 거의 괜찮아 보입니다. 실제로 내용을 추가하려면 cat및 를 추가하기만 하면 됩니다 .>>

for i in /var/abc/*.csv; do cat "$i" >> file1.csv && rm -rf "$i";done

계산하는 부분이 잘 이해가 안 되네요. 다음을 수행할 수 있습니다.

let count=0
for i in /var/abc/*.csv; do
  cat "$i" >> file1.csv && rm -rf "$i"
  let count++
done
echo $count files processed.

답변3

그리고 zsh:

files=(/var/abc/*.csv(N.))
n=0
while (($#files)) {
  cat $files[1,1000] > file$((++n)).csv &&
    rm -f $files[1,1000] || break
  files[1,1000]=()
}

관련 정보