작은 파일에 대한 몇 가지 버그 수정을 수행하려면 긴 텍스트 파일의 첫 번째 줄을 가져와야 합니다(Python 스크립트는 예상대로 큰 텍스트 파일을 소화하지 않습니다). 그러나 버그 수정이 의미가 있으려면 줄이 기본적으로 바이트 단위로 완벽한 복사본이어야 하며 문자 인코딩, 줄 끝 문자, 보이지 않는 문자 또는 보이지 않는 문자와 관련된 잠재적인 문제를 파악해야 합니다. 존재하지 않음. 다음과 같은 간단한 솔루션으로 이를 달성할 수 있습니까? 아니면 제가 사용하는 출력에 뭔가가 누락되어 있습니까 head
?
head infile.txt > output.txt
이제 head
, 또는 else를 사용한 바이너리 복사본에 대한 보다 일반적인 질문이 게시되었습니다.dd
여기.
답변1
POSIX는 입력을 의미합니다.head
는텍스트 파일, 그리고정의텍스트 파일:
3.397 텍스트 파일
0개 이상의 줄로 구성된 문자가 포함된 파일입니다. 이 줄에는 NUL 문자가 포함되어 있지 않으며
{LINE_MAX}
이 문자를 포함하여 어떤 줄도 바이트보다 길 수 없습니다<newline>
. POSIX.1-2008은 텍스트 파일과 바이너리 파일을 구분하지 않지만(ISO C 표준 참조) 많은 유틸리티는 텍스트 파일을 조작할 때 예측 가능하거나 의미 있는 출력만 생성합니다. 이러한 제한이 있는 표준 유틸리티는 항상 STDIN 또는 INPUT FILES 섹션에 "텍스트 파일"을 지정합니다.
따라서 정보가 손실될 가능성이 있습니다.
답변2
분명히 head
텍스트 파일이 아닌 경우 입력이 왜곡됩니다.
$ wc /bin/ls
431 3454 126496 /bin/ls
$ head -n 431 /bin/ls > a
wc a
431 3447 125378 a
$ diff a /bin/ls
Binary files a and /bin/ls differ
$ md5sum /bin/ls a
42846aa64774a99f0f1feba36ec2e099 /bin/ls
de032f5aa5ef356fb7d5ab4dc622df2e a
$ wc -c /bin/ls a
126496 /bin/ls
125378 a
Stéphane Chazelas는 댓글에서 좋은 지적을 했습니다.
wc -l
줄바꿈 횟수를 보고합니다./bin/ls
마지막 발생 이후에는 더 많은 바이트가 있을 수 있으며0xa
이는head -n 431
출력되지 않습니다. (귀하가 사용하고 있는 것으로 보이는) GNU 도구는 일반적으로 이진 데이터(NUL 바이트 및 임의의 긴 줄)를 처리할 수 있습니다.
따라서 사용시 출력 오류가 발생하는 이유는 head -n
마지막 문자 뒤에 추가 데이터가 있기 때문입니다 \n
. GNU 소스 코드를 보면 head
줄 읽기 기능과 바이트 읽기 기능이 모두 동일한 safe_open()
호출을 사용하므로 실제로 반환할 수 있는 것 사이에 차이가 없어야 함을 확인할 수 있습니다. 이는 GNU 구현 head
(Linux를 사용하는 대부분의 비임베디드 운영 체제에서 일반적으로 발견됨)을 사용하는 것이 매우 안전하다는 것을 보여줍니다.
man head
그러나 라인(from) 대신 바이트에서 작동하도록 지시하면 제대로 작동하는 것 같습니다.
-c, --bytes=[-]NUM
print the first NUM bytes of each file; with the leading '-',
print all but the last NUM bytes of each file
이 -c
옵션을 사용하면 동일한 파일이 생성된 것으로 나타납니다.
$ wc -c /bin/ls
126496 /bin/ls
$ head -c 126496 /bin/ls > a
$
$ md5sum /bin/ls a
42846aa64774a99f0f1feba36ec2e099 /bin/ls
42846aa64774a99f0f1feba36ec2e099 a
이는 또한 다음과 같은 결과를 얻습니다 dd
.
$ dd if=/bin/ls of=a bs=126496 count=1
1+0 records in
1+0 records out
126496 bytes (126 kB, 124 KiB) copied, 0.000469919 s, 269 MB/s
$ diff a /bin/ls
$
이 플래그를 사용할 때 항상 올바른 바이너리 출력이 생성된다는 점을 지정하는 공식 문서를 가리킬 수는 없지만 -c
합리적인 가정인 것 같습니다.
답변3
당신은 그것을 사용할 수 있습니다 split(1)
. 이렇게 하면 각 파일이 바이트 단위로 정확한 파일 조각에 해당하는 많은 파일이 생성됩니다.
예: FILE=test ; split -b 1000 $FILE $FILE.split.
1000바이트 파일 test.split.aa 및 test.split.ab 등이 생성되고 cat $FILE.split.* > $FILE.recompose
$FILE.recompose는 원본 $FILE과 동일하게 생성됩니다. 파일이 1000*26*26보다 큰 경우 접미사 길이를 늘려야 합니다( 참조 man split
).
이를 사용하면 split -l 100
각 파일에 100줄이 배치됩니다. 나는 이것이 바이트 정확할 것이라고 확신합니다.