파일 내용을 stdout으로 출력하는 명령?


28

나는 cat이것을 할 수 있지만, 주된 목적은 단순히 내용을 표시하는 것이 아니라 연결하는 것입니다.

나는 또한에 대해 알고 less하고 more,하지만 난 뭔가 간단한 (찾고 있어요 되지 호출기 바로 단말기에 파일의 내용을 출력)과 같은 것은 존재하는 경우,이를 위해 특별히 만들어졌다.


1
실제로 cat을 사용하는 시간의 99 %는 무엇이든 연결하지 않고 파일을 표시하는 것입니다.
LatinSuD

1
@LatinSuD-시간의 100 %- cat연결합니다.
mikeserv

@ mikeserv : 그것은 작업을 수행하여 의미하는 바입니다. 일반적인 언어 사용은 한 번 이상 수행되었음을 암시하는 것입니다. 빈 문자열 "인쇄"에는 문자 인쇄가 필요하지 않습니다. 아무 것도 인쇄하지 않는다고 말하는 것이 공정합니다. 이제 컴퓨팅 a+b+c에는 2 개의 덧셈을 수행해야하며 컴퓨팅 a에는 아무 것도 추가하지 않습니다. 마찬가지로 실행 cat f은 아무것도 연결하는 것을 포함하지 않습니다 (이것이 "하나의 파일 시퀀스를 연결하는"유일한 의미 임에도 불구하고).
Marc van Leeuwen

2
@ mikeserv : in + out의 의미를 알 수 없습니다. 물론 cat파일을 읽고 다른 파일 (스트림)을 작성하지만 이것이 파일을 연결한다는 의미는 아닙니다. 그것이 cat f실제로하고 있다는 것을 의미한다면 cat - f, 그것은 사실이 아닙니다.
Marc van Leeuwen

1
@ confused00 : cat실제로 연결하기위한 cat file1 file2것입니다 ( 두 파일을 stdout에 연결합니다). 그러나 부작용은 하나의 파일을 인수로 가질 때 하나의 파일을 표준 출력으로 출력한다는 것입니다 (터미널 또는 다른 곳으로 리디렉션되는 곳). 따라서 stdout에서 출력하기 위해 작성된 다른 명령은 없었 cat으며 단순히 허용했습니다. 따라서을 사용하고 싶습니다 cat.
Olivier Dulac

답변:


37

가장 확실한 것은입니다 cat. 그러나, 또한 한 번 봐 가지고 headtail. 파일을 줄을 인쇄 할 다른 쉘 utillities도 있습니다 : sed, awk, grep. 그러나 파일 내용을 대체하거나 파일 내부를 검색해야합니다.

가장 효과적인 테스트를 몇 가지 테스트했습니다. strace어떤 시스템 호출을 가장 적게했는지 확인하기 위해 모든 구유 를 실행 합니다. 내 파일에는 1275 줄이 있습니다.

  • awk: 1355 시스템 호출
  • cat: 51 시스템 호출
  • grep: 1337 시스템 호출
  • head: 93 시스템 호출
  • tail: 130 시스템 호출
  • sed: 1378 시스템 호출

보다시피, cat파일을 연결하도록 설계 되었더라도 가장 빠르고 효과적인 파일입니다. sed, awkgrep, 라인하여 파일 라인을 인쇄하는 그들은 더 많은 것을 1275 시스템 호출을 이유.


8
시스템 콜을 세는 것이 좋습니다!
Jan

1
+1, 답변의 정확성 (고양이 의미),보다 완전하고 (대체), 연구 (시스템 콜)
Olivier Dulac

23

나는 cat이것을 할 수 있지만, 주된 목적은 단순히 내용을 표시하는 것이 아니라 연결하는 것입니다.

목적 cat은 정확히 파일을 읽고 stdout으로 출력하는 것입니다.


1
그러나 cat --help"FILE (s) 또는 표준 입력을 표준 출력에 연결합니다"라고 말합니다. 나는 아무것도 연결하고 싶지 않다
confused00

18
믿거 나 말거나, 고양이는 정확히 당신이 찾고있는 것입니다.
1

5
아니요, @ confused00, Jan이 옳습니다. 문제는-터미널 표준입니다-알 수 있습니까? 할 readlink /dev/fd/1- 예를 들어, 당신은 거기에 청각 장애의 이름을 얻어야한다 프롬프트 표준에서 실행되는 경우. 따라서 입력을 출력에 연결하는 것이 요구하는 것입니다.
mikeserv

2
@ mikeserv 그래, 당신의 요점을 참조, 나는 '연결'의 의미에 너무 고정 된 것 같아요.
confused00

3
논리는,의 내용을 인쇄하고 하나 개의 파일은의 내용을 인쇄 단지 특별한 경우 하나 개 이상의 순서로 파일을.
zwol

10

먼저, 대화식 쉘에 대한 명령의 일부로 입력 된 cat경우에도 반드시 터미널이 아닌 표준 출력에 기록합니다 cat. 표준 출력이 리디렉션 될 때에도 실제로 터미널에 쓸 무언가가 필요한 경우 그렇게 쉽지 않습니다 (어떤 터미널을 지정해야하며 명령이 스크립트에서 실행되는 경우 터미널이 없을 수도 있음). 명령이 파이프 라인의 일부인 경우 표준 오류 출력을 사용할 수 있습니다. 그러나 cat실제로 작업을 수행한다고 표시했기 때문에 그러한 상황에 대해 묻지 않았다고 가정합니다.

당신의 목적은 파이프 라인으로 표준 출력에 기록됩니다 무엇을 전송한다면, 다음 사용하여 cat받는 자격이 될 것 고양이 상 쓸모 사용 하기 때문에, cat file | pipeline(여기서 pipeline어떤 파이프 라인의 약자)를보다 효율적으로 수행 할 수 있습니다 <file pipeline. 그러나 다시 말하지만, 나는 이것이 당신의 의도가 아니라고 추론합니다.

그래서 당신이 무엇을 걱정하는지 명확하지 않습니다. 당신이 찾아내는 경우에 cat입력하는 데 시간이 너무 오래, 당신은 (표준 유닉스에서 사용되지 않는 남아있는 몇 등의 이름이 여전히있다)는 1 또는 2 문자 별칭을 정의 할 수 있습니다. 그러나 그것이 cat쓸모없는 사이클을 소비 하고 있다고 걱정한다면 , 그렇게해서는 안됩니다.

null인수를 사용하지 않고 표준 입력을 표준 출력 (파이프 라인의 중립 객체)에 복사 하는 프로그램 이 있다면 원하는 작업을 수행 할 수 있습니다 <file null. 작성하기는 쉽지만 (한 줄 main함수 만있는 C 프로그램 이 작업을 수행 할 수는 있지만) 그러한 프로그램은 없지만 cat인수없이 (또는 cat -명시 적으로 표현하려는 경우) 호출 하면됩니다.

이 있다면 nocat단 하나 개의 파일 이름 인수를 취하는 프로그램을 할 수없는 경우를 불평, 파일을 열려고 시도하고, 그렇지 않으면, 그 다음은 당신이 요구하는 단지 어떤 것이 표준 출력에 파일 복사로 진행한다. null, 파일을 열고 테스트하고 불만을 제기하는 주요 작업 보다 쓰기가 약간 어렵습니다 . 그러나 cat이제는 단일 인수가 제공되므로 다시 수행 할 필요가 없으므로 nocat프로그램이 필요하지 않습니다 .

nocat프로그램 작성에 성공하면 왜 단일 논쟁에서 멈출까요? 코드를 루프로 감싸는 for(;*argp!=NULL;++argp)것은 전혀 노력할 필요가 없으며 바이너리에 최대 두 개의 기계 명령어를 추가하며 잘못된 수의 인수에 대해 불평하지 않아도됩니다 (더 많은 명령어가 필요함). cat파일을 연결 하는 기본 버전의 Voilà . (솔직히 말해서 인수없이 작동하도록 약간 조정해야합니다 null.)

물론 실제 cat프로그램에서 그들은 항상하기 때문에 몇 가지 종소리와 휘파람을 추가했습니다. 그러나 본질적인 점은 cat비용 의 "연결"측면 이 전혀 노력을 기울이지 않고 프로그래머 나 기계를 실행하는 데 전혀 도움이되지 않는다는 것입니다. 그러한 프로그램이 존재하지 cat않는다고 가정 null하고 nocat설명하는 사실 . cat결과가 파이프 라인에 들어가는 경우 단일 인수를 사용하지 말고 터미널에 파일 내용을 표시하는 데만 사용되는 경우 링크 된 페이지조차도 이것이 유용한 사용법이라는 것을 인정 cat하므로 주저하지 마십시오.


첫 번째 위치가 아닌 하나의 유효하지 않은 이름을 가진 여러 파일 이름 을 호출 cat하여 가상 nocat기능을 둘러싼 간단한 루프로 실제로 구현되는지 테스트 할 수 있습니다 cat.이 파일이 존재하지 않는다고 즉시 불만을 제기하지 않고 cat먼저 선행 파일을 덤프합니다. 유효한 파일을 찾은 다음 잘못된 파일에 대해 불평합니다 (적어도 내 고양이의 행동 방식).


7

에서 zsh시도

<file

파일을 인쇄하는 가장 짧은 방법이라고 생각합니다. 'hidden' cat(또는 morestdout이 터미널 인 경우)을 사용하지만 인쇄에 사용되는 명령은 READNULLCMD변수에 의해 제어 되므로 명령 이름이나 일부 기능으로 직접 덮어 쓸 수 있습니다. 예를 들어 줄 번호가 지정된 파일을 인쇄하려면

numcat() { nl -s'> ' -w2 - }
READNULLCMD=numcat
<file

5

POSIX는 고양이 를 다음과 같이 정의 합니다.

이름

고양이-파일 연결 및 인쇄

개요

고양이 [-u] [파일 ...]

기술

cat 유틸리티는 파일을 순서대로 읽고 내용을 동일한 순서로 표준 출력에 기록해야합니다.

따라서 여기서 연결 한다는 것은 파일을 순서대로 읽는 것을 의미 한다고 생각 합니다 .


5

나는 이것이 과거의 긴장된 질문이라는 것을 알고 있습니다. 기술적으로 파일의 내용 stdout을 연결 형식으로 인쇄하는 cat것이 의미 적으로 적합합니다. printf의미 적으로 데이터를 형식화하고 인쇄하기위한 것임을 잊지 마십시오 . Bash는 또한 파일의 입력 및 출력을 리디렉션하는 구문을 제공합니다. 이들을 조합하면 다음과 같은 결과가 발생할 수 있습니다.

printf '%s' "$(<file.txt)"

4
특히 원형 교차로 외에 표시되는 명령은 cat file.txt후행 줄 바꿈을 제거하므로이 명령과 동일 $(...)하지 않습니다 (이 작업을 수행함 ).
Marc van Leeuwen

+1, 잘 잡습니다. 몰랐어요
James M. Lay

3

bash내장 사용 및 서브 프로세스 작성 피하기 :

{ while IFS='' read -rd '' _bcat_; do printf '%s\0' "${_bcat_}"; done; printf '%s' "${_bcat_}"; unset _bcat_; } <'/path/to/file'

IFSread명령 에만 적용 되므로 전역 IFS변경 에 대해 걱정하지 마십시오 .

null 문자를 처리하는 데 필요한 루프 (Stéphane Chazelas 덕분에).

이 방법은 파일 내용이 먼저 변수 (메모리)를 읽으므로 큰 파일에는 적합하지 않습니다. BTW 39M 텍스트 파일을 이런 식으로 인쇄하려고했는데 bash 메모리 사용량이 5M을 초과하지 않았 으므로이 경우에 대해서는 확실하지 않습니다.

또한 39M 파일의 경우 단일 코어를 100 % 사용하는 데 약 3 분이 걸렸습니다.

큰 파일이나 이진 파일을 사용하는 것이 더 좋 cat '/path/to/file'거나 가능 dd if='/path/to/file' bs=1M하다면 더 좋습니다 .


1
pv -qLinux splice()에서 어떤 유형의 stdin / stdout에 성능을 향상시킬 수있는 것을 참조하십시오 .
Stéphane Chazelas

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