파일을 분할 한 후 다시 결합하는 가장 좋은 방법은 무엇입니까?


73

큰 파일이 있고 100MB 청크로 분할해야하는 경우

split -b 100m myImage.iso

보통은 나에게

xaa
xab
xac
xad

그리고 그들을 다시 모으기 위해

cat x* > myImage.iso

파일 그룹에서 각 코드 줄을 읽고 cat출력을 새 파일로 리디렉션하는 것보다 효율적인 방법이 있어야 합니다. 두 개의 파일을 열고 EOF첫 번째 파일에서 마커를 제거한 다음 모든 내용을 거치지 않고 연결하는 방법과 같습니다.

Windows / DOS에는 이진 파일에 대한 복사 명령이 있습니다. 도움말에서는이 명령이 여러 파일을 결합 할 수 있도록 설계되었다고 언급합니다. 이 구문으로 작동합니다 : ( /b이진 모드입니다)

copy /b file1 + file2 + file3 outputfile

Linux에서 고양이보다 큰 파일을 결합하는 비슷한 방법이나 더 좋은 방법이 있습니까?

최신 정보

cat실제로 파일을 결합하는 올바른 방법과 최상의 방법 인 것 같습니다 . 내가 올바른 명령을 함께 사용하고 있다는 것을 알게되어 기쁘다.


22
참고 : cat x*파일 순서는 로캘 설정에 따라 다르므로 사용하지 않는 것이 좋습니다 . Esc 키 를 누른 cat x것 보다을 입력하는 것이 좋습니다. 확장 된 파일 순서를보고 다시 정렬 할 수 있습니다. *
rozcietrzewiacz

16
대신 cat x*쉘 괄호 확장을 고려 cat xa{a..g}하여 지정된 시퀀스를 cat xaa xab xac xad xae xaf xag
Peter로

3
@rozcietrzewiacz-내가 로케일 설정을 조정하는 방법에 대한 예를 들어 줄 수 cat x*있습니까? 새로운 로케일 설정은 영향을주지 않을까요 split경우 너무 splitcat x*동일한 시스템에 사용 된 그들은 항상 일 것이다?
cwd

3
"첫 번째에서 EOF 마커를 제거, 두 개의 파일을 열고, 그들을 연결 -. 모든 내용을 통해 이동하지 않고"당신은 당신이 원하는 일을하기 위해 새로운 파일 시스템을 발명 할 필요가처럼 ... 소리
JoelFan

6
@cwd : split.cGNU Coreutils에서 접미사는 고정 된 문자 배열로 구성됩니다 static char const *suffix_alphabet = "abcdefghijklmnopqrstuvwxyz";. 접미사는 로케일의 영향을받지 않습니다. (그러나 나는 제정신 로케일이 소문자를 재정렬한다고 생각하지 않습니다. 심지어 EBCDIC조차도 표준 순서를 유지합니다.)
Keith Thompson

답변:


50

그것은 단지 cat만들어진 것입니다. 가장 오래된 GNU 도구 중 하나이기 때문에 다른 도구가 더 빠르거나 더 나은 것 같지는 않습니다. 그리고 그것은 배관 이 아닙니다 -출력을 리디렉션하는 것입니다.


cat x, then press Esc당신이 언급 한 트릭이 깔끔하네요 .. 나는 그런 일, 덕분에 ... 좋은 의견과 좋은 대답을 찾고 있었어요
Peter.O

2
당신은 환영합니다 :) 또한 명령 줄에 해당 파일 목록이 있으면 Ctrl+W단어를 잘라낸 다음 Ctrl+Y붙여 넣을 수 있습니다.
rozcietrzewiacz

고양이는 "연결하다"를 의미
JoelFan

4
.. 및 "catenate"는 "체인"을 의미하는 라틴어 "catena"에서 파생됩니다. 연결 은 체인의 링크를 연결합니다. ... (그리고 조금 더 주제가 아닌, 전차 곡선 도 "카테 나"에서 파생됩니다. 그것은 사슬이
멈추는

19

후드

첫 번째 파일을 복사 한 다음 두 번째 파일을 복사하는 등의 효율적인 방법은 없습니다. DOS copycat그렇게하세요.

각 파일은 디스크의 다른 파일과 독립적으로 저장됩니다. 디스크와 같은 장치에 데이터를 저장하도록 설계된 거의 모든 파일 시스템은 블록별로 작동합니다. 디스크는 1kB의 블록으로 나뉘며 각 파일에 대해 운영 체제는 디스크를 구성하는 블록 목록을 저장합니다. 대부분의 파일은 정수 블록의 길이가 아니므로 마지막 블록은 부분적으로 만 채워집니다. 실제로 파일 시스템은 여러 파일간에 마지막 부분 블록을 공유하거나 "블록 46798, 블록 46799,…"대신 "블록 46798 ~ 47913"을 저장하는 등 많은 최적화 기능을 가지고 있습니다. 운영 체제가 새 파일을 작성해야 할 때 사용 가능한 블록을 찾습니다. 블록이 연속적 일 필요는 없습니다. 블록 4, 5, 98 및 178 만 사용 가능한 경우 4kB 파일을 계속 저장할 수 있습니다.

파일 중간에 부분 블록을 지원할 수는 있지만 특히 비 순차적으로 파일에 액세스 할 때 상당히 복잡해집니다. 10340 번째 바이트로 이동하면 더 이상 11 번째 블록의 100 번째 바이트로 이동할 수 없습니다. 모든 중간 블록의 길이를 확인하십시오.

블록을 사용하면 일반적으로 첫 번째 파일이 중간 블록으로 끝나기 때문에 두 파일을 결합 할 수 없습니다. 물론 특별한 경우가 있지만 연결할 때 두 파일을 모두 삭제하려는 경우에만 가능합니다. 이는 드문 작업에 대한 매우 구체적인 처리 방법입니다. 일반적인 파일 시스템에서는 많은 파일이 동시에 액세스되기 때문에 이러한 특수 처리는 자체적으로 수행되지 않습니다. 따라서 최적화를 추가하려면 다른 프로세스가 관련된 파일 중 하나를 읽는 경우 어떻게됩니까? 누군가 A와 C를 연결하는 동안 누군가 A와 B를 연결하려고하면 어떻게됩니까? 등등. 대체로이 드문 최적화는 큰 부담이 될 것입니다.

대체로 다른 곳에서 큰 희생을 치르지 않고 파일을보다 효율적으로 결합 할 수는 없습니다. 그것은 가치가 없어.

분할 및 가입

splitcat분할 및 결합 파일의 간단한 방법이 있습니다. split알파벳 순서로 이름이 지정된 파일을 생성하므로 cat *결합에 효과적입니다.

cat결합 의 단점은 일반적인 실패 모드에 비해 강력하지 않다는 것입니다. 파일 중 하나가 잘 리거나 누락 되어도 cat불평하지 않으면 출력이 손상됩니다.

같은 다중 아카이브 생성 압축 유틸리티가있다 zipsplitrar -v. 그것들은 분할 외에도 압축 및 압축 (여러 파일을 하나로 묶음) 및 결합과 함께 압축을 풀고 압축을 풀기 때문에 매우 유쾌하지 않습니다. 그러나 모든 부품이 있고 부품이 완전한지 확인하는 데 유용합니다.


8

모든 내용을 시스템의 stdin/를 통해 파이프하는 것보다 효율적인 방법이 있어야합니다stdout

그것이 실제로 일어나지 않는 것을 제외하고. 쉘은 stdout을 열린 파일 에 cat 직접 연결하고 있는데, 이는 "stdout을 통한 이동"이 디스크에 쓰는 것과 동일하다는 것을 의미합니다.


나는 고양이를 사용하여 콘솔에 몇 기가 바이트의 코드를 표시 한 다음 캡처하고 파일에 넣는 것을 상상하고있었습니다. 그것은 고양이를 사용하고 볼 수없는 출력을 리디렉션 할 때 일어나야 할 일에 대한 정신 이미지입니다. 두 개의 파일을 열고 연결 한 다음 닫는 방법이 있다면 모든 코드 줄을 실행하는 것보다 낫습니다 cat. 직접 연결에 대해 알려 주셔서 감사합니다.
cwd

@cwd 두 개의 파일을 그런 식으로 결합 할 수있는 파일 시스템을 설계 할 수는 있지만 파일 시스템의 설계가 엄청나게 복잡해집니다. 많은 일반 작업을 더 복잡하고 느리게 만드는 비용으로 해당 작업 하나를 최적화합니다.
Gilles

@Gilles-저수준 세부 정보에 대해 더 많이 알고 있으면 흥미로울 것입니다. 나에게, 여러 파일에 대해 하드 디스크에서 모든 섹터를 읽은 다음 디스크의 다른 사용되지 않은 섹터로 다시 덤프하는 것은 비효율적입니다. 그리고 큰 파일은 여러 블록의 빈 섹터에 걸쳐 저장해야한다고 생각합니다. 블록을 저장하기에 충분한 블록이 항상있을 수는 없기 때문입니다. 따라서 이론적으로 EOF 마커를 제거하고 다음 파일의 시작 부분에서 섹터 그룹을 가리키면 파일을 하나로 결합 할 수 있습니다. * nix는 강력하므로 고양이보다 더 좋은 방법이 있는지 궁금합니다.
cwd

@cwd“EOF 마커”가 없습니다. 파일에서 일부 문자가 발생하지 못하게하거나 복잡한 인코딩이 필요한 현대적인 파일 시스템은 그렇게 작동하지 않습니다. 그러나 EOF 마커가 있더라도 대부분 그 뒤에 올바른 파일이 없습니다.
Gilles

나는 실제 EOF 마커가 아니라 EOF 마커의 개념을 의미했다. 그렇지 않으면 하드 드라이브에서 파일의 비트와 바이트를 보면 파일의 끝을 어떻게 알 수 있습니까? 파일의 시작 부분에 파일 길이를 지정합니까? 나는 정말로 저수준에 대해 이야기하고 있습니다. 그게 당신도 언급하고 있습니까?
cwd

3

한 번만이 문제가 발생했습니다. 일부 파일을 결합하고 싶었지만 디스크 공간이 부족하여 이중으로 저장할 수 없었습니다.

그래서 나는 많은 프로그램을 썼다.

  • 하나는 파일을 읽고 stdout으로 전송하고, 완료되면 제거하여 파일을 "빨리"
  • 하나는 "즉석에서"데이터를 버퍼링합니다.

이를 통해 다음과 같은 작업을 수행 할 수있었습니다.

partto sourcefile | mybuffer 128M >>cumufile

따라서 128M이 아직 기록되지 않은 상태에서 소스 파일을 제거합니다. 조금 위험하지만 데이터가 그다지 귀중하지 않거나 다른 곳에 존재한다면 가능합니다.

필요한 경우 소스를 제공 할 수 있습니다.


0

엄밀히 말하면, 이것은 전체 내용을 읽고 쓰지 않고도 전체 파일에 액세스하는 방법이며, 큰 파일이나 공간이 거의없는 경우 유용 할 수 있습니다.

$ mkfifo myImage.iso
$ cat xa{a..g} > myImage.iso &

그런 다음 myImage.iso예를 들어

$ md5sum myImage.iso

물론 myImage.iso일반 파일이 아닌 특수 파일 (파이프라는 이름의 파일)이지만 사용하려는 작업에 따라 사용 중이거나 그렇지 않을 수 있습니다.


0

파일 분할

크기로 나누기

큰 파일을 작은 파일로 분할하고 작은 출력 파일의 이름과 크기를 선택하려면이 방법입니다.

split -b 500M videos\BigVideoFile.avi SmallFile.

이 방법으로 하나의 큰 파일을 500MB의 작은 부분으로 분할하도록 선택합니다. 또한 부품 파일 이름이 SmallFile이되기를 원합니다. 참고 이 점 필요 파일 이름 뒤에. 결과는 다음과 같은 새 파일을 생성해야합니다.

SmallFile.ab SmallFile.ad SmallFile.af SmallFile.ah SmallFile.aj
SmallFile.aa SmallFile.ac SmallFile.ae SmallFile.ag SmallFile.ai SmallFile.ak
...

줄 수로 나누기

이렇게하면 텍스트 파일을 50 줄로 제한되는 작은 파일로 분할 할 수 있습니다.

split -l 50 text_to_split.txt

결과는 다음과 같아야합니다.

xaa xab xac ...

바이트로 나누기

작은 크기의 파일을 바이트 단위로 작은 파일로 분할 :

split -b 2048 BigFile.mp4

결과는 행 수로 분할의 결과와 유사해야합니다 .

결합하는 파일

두 가지 방법으로 파일을 결합 할 수 있습니다. 첫 번째는 :

cat SmallFile.* > OutputBigVideoFile.avi

또는 함께 :

cat SmallFile.?? > OutputBigVideoFile.avi

참고 : 파일을 결합 할 때 작은 파일은 손상되지 않아야합니다. 또한 모든 작은 (부분) 파일은 동일한 디렉토리에 있어야합니다.

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.