cat 명령에서 첫 번째 X 문자를 얻습니까?


41

쉘 스크립트에서 변수로 출력하는 텍스트 파일이 있습니다. 그러나 처음 50 자만 필요합니다.

사용을 시도 cat ${filename} cut -c1-50했지만 처음 50 자 이상을 사용하고 있습니까? cut이 텍스트 파일은 하나의 긴 문자열 일 수 있지만 실제로 의존하는 행 을 찾은 것일 수 있습니다 (100 % 확실하지 않음).

cat명령 에서 첫 번째 X 문자를 얻기 위해 파이프로 연결할 수있는 유틸리티가 있습니까?


10
당신은 잊었다 |? cat ${filename} | cut -c1-50
DisplayName

재 입력 오류를 잡아 주셔서 @DisplayName이 수정되었습니다.
jkj2000

1
@ jkj2000, 원래 질문이므로 이전 버전으로 되돌 렸습니다.
Ramesh

답변:


61
head -c 50 file

처음 50 바이트를 반환합니다.

모든 OS에서 명령이 항상 동일하게 구현되는 것은 아닙니다. Linux 및 macOS에서는이 방식으로 작동합니다. Solaris (11)에서 / usr / gnu / bin /의 gnu 버전을 사용해야합니다.


헤드-c옵션 이 없습니다 . 대신 dd (1) 로 갈 것입니다 .
mirabilos

6
이 대답은 OP가 바이트가 아닌 첫 번째 X 문자를 요청한 것처럼 파일에 ASCII 문자 만 포함한다고 가정합니다.
Calimo

2
@mirabilos 이식성이 없을 수도 있지만 내 버전 ( GNU coreutils 5.97)이 그렇지 않습니다.
Yossarian

1
POSIX는 -c유효한 옵션으로 정의되지 않으므로 로컬 환경에 따라 다릅니다. unix.com/man-page/posix/1/head
Jules

1
@Calimo 예, 알고 있습니다.하지만 100 자로 텍스트 파일을 만든 다음 명령을 실행하려고 시도했는데 50자가 인쇄되었습니다. 그러나 당신은 ASCII에 대해서는 옳습니다. 그러나 OP가 이것을 대답 한 것으로 표시 한 이후 그의 경우에는 아무도 없었습니다.
DisplayName

27

당신의 cut당신이 그것에 데이터를 전달하는 파이프를 사용하는 경우 명령은 작동합니다 :

cat ${file} | cut -c1-50 

또는 쓸모없는 고양이 사용을 피하고 조금 더 안전하게 만듭니다.

cut -c1-50 < "$file"

위의 명령 은 각 입력 행 의 처음 50 자 (또는 cut구현 에 따라 바이트)를 인쇄합니다 . 말한 것처럼 파일이 큰 줄이면 예상대로해야합니다.


8
dd status=none bs=1 count=50 if=${filename}

처음 50 바이트를 반환합니다.


dd 에는 status=none플래그 가 없습니다 . 사용 2>/dev/null대신에 (제대로 인용) : dd if="$filename" bs=1 count=50 2>/dev/null(그렇다고하더라도, 사용을 고려 bs=50 count=1관련된 시스템 콜의 수를 줄이기 위해).
mirabilos

1
@mirabilos dd는 status=noneUbuntu 14.04, coreutils 8.21을 사용할 때 가지고 있지만 2>/dev/null이전 버전 을 사용하는 경우 사용하는 것이 좋습니다 .
doneal24

1
@mirabilos 대부분의 Linux 배포판은 FreeBSD 및 기타 BSD와 마찬가지로 GNU coreutils를 사용합니다. Solaris에서 gnu-coreutils 패키지로 제공됩니다. 예, 이것은 "Unix & Linux"이며 Unix 및 Linux 시스템은 모두 GNU coreutils를 사용합니다.
doneal24

2
아닙니다. 유닉스 시스템은 일반적으로 GNU 유틸리티를 사용하지 않습니다. GNU는“GNU는 유닉스가 아닙니다”의 약자입니다. 휴대용 솔루션을 고수하거나 GNU 전용 솔루션을 제공 해야하는 경우에는 그렇게하고, 가능한 경우 동등한 휴대용 솔루션을 보여주십시오.
mirabilos

1
엄밀히 말하면, 그것은 read()50 바이트 중 하나 를 수행합니다. (가) 경우 file예를 적은 문자 파이프가 한 번에 사용할 수있는 것입니다, 다음 적은 바이트가 반환됩니다. 에 해당하는 head -c50것을 사용하려면 GNU specific을 사용해야합니다 iflag=fullblock.
Stéphane Chazelas

4

지금까지 대부분의 답변은 1 바이트 = 1 문자로 가정하며 ASCII가 아닌 로케일을 사용하는 경우에는 그렇지 않을 수 있습니다.

약간 더 강력한 방법 :

testString=$(head -c 200 < "${filename}") &&
  printf '%s\n' "${testString:0:50}"

이것은 다음을 가정합니다.

  1. 당신이 사용하고 ksh93, bash(또는 최근 zsh또는 mksh지원하는 유일한 멀티 바이트 문자 집합 생각하는 것은 ( mkshUTF-8 만 이후 set -o utf8-mode및 버전)) head가 지원 -c(대부분의 요즘,하지만 엄격하게 표준되지 않음).
  2. 현재 로케일은 파일과 동일한 인코딩으로 설정됩니다 (유형 locale charmapfile -- "$filename"확인). 그렇지 않으면 ie로 설정하십시오. LC_ALL=en_US.UTF-8)
  3. head모든 문자가 최대 4 바이트로 인코딩되는 최악의 경우 UTF-8을 가정 하여 파일의 처음 200 바이트를 사용했습니다 . 이것은 내가 생각할 수있는 대부분의 경우를 다루어야합니다.

물론 이것은 GNU head또는 nōn-standard -c옵션 을 추가하는 또 다른 구현을 가정합니다 . 그러나 이미 GNU bash가 필요합니다. (참고 : mkshUTF-8 모드는 UTF-8로 인코딩 된 파일에 대해이 작업을 수행 할 수 있습니다.) OP에 옥텟 또는 멀티 바이트 문자가 필요한지 물어 보면 "문자"만 모호한 / gerneric 용어입니다.
mirabilos

또한 빈 줄 바꿈이나 와일드 카드를 포함 $filename하거나 $testString포함하지 않는다고 가정합니다 -.
Stéphane Chazelas

${var:offset:length}여기에서 사용 하는 구문은 실제로 제공 ksh93되며 최신 버전 zsh( zsh자체 있음 $testString[1,50]) 에서도 지원됩니다 . 당신은 필요 ${testString:0:50}ksh93하고 zsh그러나.
Stéphane Chazelas

위의 의견을 해결하기 위해 내 답변을 편집했습니다.
Calimo

2
grep -om1 "^.\{50\}" ${filename}

다른 변형 (파일의 첫 줄)

(IFS= read -r line <${filename}; echo ${line:0:50})

이는 고급 도구를 남용하는 것이므로 로케일을 인식하는 등 원하는 작업을 수행하지 않는 경향이 있습니다.
mirabilos

@mirabilos 당신은 무엇을 아래에 뜻 높은 수준의 도구 : readecho? 아니면 bash expansion?
Costas

grep(regexp), 그렇습니다. 여기서는 쉘을 사용합니다 (힌트 : 첫 번째 줄이 클 수 있습니다). (이것으로 말하면, bashism은 POSIX에도 없지만 대부분의 쉘은 그것을 구현합니다.)
mirabilos

0

1. ASCII 파일의 경우 @DisplayName과 같이 수행하십시오 .

head -c 50 file.txt

예를 들어 file.txt의 처음 50자를 인쇄합니다.

2. 이진 데이터의 경우 hexdump16 진 문자로 인쇄하는 데 사용하십시오 .

hexdump -n 50 -v file.bin

예를 들어 file.bin의 처음 50 바이트를 인쇄합니다.

-vverbose 옵션 을 사용하지 않으면 hexdump반복되는 줄이 별표 ( *)로 바뀝니다. 여기를 참조하십시오 https://superuser.com/questions/494245/what-does-an-asterisk-mean-in-hexdump-output/494613#494613 .


-2

sed를 사용하면 문제를 쉽게 해결할 수 있습니다.

sed -e 's/^\(.\{50\}\).*/\1/' yourfile

UUOC (고양이의 쓸모없는 사용)하지 않고 요청 된 것을이 달성 "나는 첫 번째 50 자 필요":이는 영업 이익의 문제가 해결되는지을 downvoted 됐는지 알고 있어요
munkeyoto

1
이 대답은 파일의 처음 50 개뿐만 아니라 파일에서 각 줄의 처음 50자를 제공합니다. 모든 줄의 길이가 50 자 미만인 경우에도 아무 것도 인쇄하지 않습니다. 솔루션이 더 잘 작동합니다sed -n -e '1s/^\(.\{50\}\).*/\1/p' ${filename}
doneal24

이해할 수있는 것 : head -n 1 | sed -e 's / ^ (. \ {50 \}). * / \ 1 /'... 그리고 문제를 해결했을 것입니다. OP는 다음과 같이 언급했다 : "처음 50 자만 필요"
munkeyoto

1
아니. 첫 번째 줄의 길이가 49자인 경우 아무 것도 출력하지 않습니다.
doneal24

Doug 나는 이것을 처음으로 이해했지만 OP에 줄이 50 자 미만인 경우 인쇄에 대해서는 언급하지 않았으므로 여전히 당신의 요점을 알 수 없으며, 그 이후로 여전히 하향 조정 된 요점은 head : head -n 1 $ {filename} | SED -n -e '1S / ^ (\ {50 \}.) * / \ 1 / P.'
munkeyoto
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.