를 통해 이 작업을 수행할 수 있다는 것을 알고 있습니다 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 파일을 이름이 등인 파일로 연결하여 목록과 일치시킵니다. 각 파일 세트가 복사된 후 원본 파일은 삭제됩니다.csvlists
csvlists00
csvlists01
for
concat00.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]=()
}