다음 내용이 포함된 main.txt 파일이 있다고 가정해 보겠습니다.
일부 텍스트
#조각 1.txt 포함
다른 텍스트
#includefragment2.txt"
다른 텍스트
그 중 조각1.txt와 조각2.txt는 다음과 같습니다.
조각 1.txt:
이것은 조각 1의 내용입니다.
조각 2.txt:
이것은 조각 2의 내용입니다.
질문: 다음과 같이 "확장" 포함 파일을 사용하여 전체 main.txt 파일을 표시하는 방법:
일부 텍스트
이것은 조각 1의 내용입니다.
다른 텍스트
이것은 조각 2의 내용입니다.
다른 텍스트
감사해요
답변1
C 프로그래밍 언어의 구문을 사용하려는 경우 이를 구문 분석하는 데 #include "file"
사용할 수 있습니다 . cpp
예를 들어 main.txt
다음과 같은 경우:
Some text
#include "fragment1.txt"
Some other text
#include "fragment2.txt"
Some other text
다음을 수행할 수 있습니다.
$ cpp -nostdinc -P <main.txt
Some text
This is content of fragment1
Some other text
This is content of fragment2
Some other text
설명된 대로 man cpp
:
-nostdinc 헤더 파일에 대한 표준 시스템 디렉터리를 검색하지 않습니다. -I 옵션으로 지정된 디렉터리(해당되는 경우 현재 파일의 디렉터리)만 검색합니다.
-P 전처리기 출력에서 라인 마커 생성을 억제합니다. 이는 C가 아닌 코드에서 전처리기를 실행할 때 유용할 수 있으며 라인 마커로 인해 혼동될 수 있는 프로그램으로 전송됩니다.
그러나 이것은 cpp
단지 라인 구문 분석에 관한 것이 아니며 #include
사용 사례에 따라 유용할 수도 있고 그렇지 않을 수도 있습니다. 예를 들어 cpp
모든 C 스타일 주석을 자동으로 제거하려면 다음을 수행하십시오.
// this is a comment
/* this as a comment too /*
유용해 보이며 -C
댓글을 유지하려는 경우 옵션이 있습니다. 또 다른 점은 전처리기 지시문으로 시작하는 cpp
모든 줄을 해석하려고 시도 한다는 것입니다. #
예를 들면 다음과 같습니다.
#define A 7
Value: A
다음과 같이 인쇄됩니다:
Value: 7
이
#blah blah
오류가 발생합니다:
<stdin>:14:2: error: invalid preprocessing directive #blah
실제로 cpp
구성 파서로 의존하는 일부 프로그램이 있습니다 xrdb
.
답변2
#include
작은 스크립트 로 리터럴 문제를 해결할 수 있지만
재귀적일 수는 없습니다. 파일 자체를 포함하면 무한 루프가 발생하며
필요에 따라 재귀적 포함이 지정되지 않습니다.
결국 실제 파서가 필요할 수 있습니다. 다른 답변을 참조할 수 있습니다.
표준 입력을 통해 main.txt
다음 Perl 스크립트를 입력하면
출력은 (대략) 원하는 출력이 됩니다.
awk도 그 일을 할 수 있지만 저는 Perl의 신비로움을 좋아합니다 :)
#!/usr/bin/perl
while (<>) {
if (/^#include (.*)/) {
system('cat',$1);
} else {
print;
}
}
위 코드의 더 짧은 한 줄 버전:
perl -e '(/^#include (.*)/ ? system("cat",$1) : print) while <>;' <main.txt
Perl에 대해 더 자세히 알고 싶은 분들을 위해:
<>
STDIN
표준 입력 스트림인 read from 의 약어입니다 .키워드는
while
줄 끝에 배치할 수 있으며()
모호한 해석이 없으면 생략할 수 있습니다.에서 읽은 각 줄에 대해
STDIN
Perl은 이를 다음 위치에 저장합니다.$_
$_
매개변수가 제공되지 않을 때 대부분의 Perl 내장 함수가 매개변수로 허용하는 사전 정의된 변수입니다.print
다음을 허용하는 내장 함수 중 하나입니다.$_
각 줄을 읽은 후 Perl은 삼항 표현식을 평가합니다. 정규식 일치가
$_
기본적으로 적용됩니다./^#include (.*)/
1(검색된 일치 항목 수)을 반환 하면$_
텍스트로 시작한다는 의미입니다.#include
$_
Perl은 to의 나머지 부분을$1
첫 번째 그룹 캡처이므로 저장합니다(그룹이 더 있으면 $2,$3...정의됨).이
system
함수는 시스템 셸을 통해 주로sh
이 줄에서cat
인수$1
로 전달된 명령을 호출합니다.0 을
/^#include (.*)/
반환 하면 평가되고 부작용으로 인쇄됩니다.$_
print
$_
삼항 표현식의 값은 자동으로 무시됩니다.
답변3
C 전처리기를 직접 실행합니다.
$ cpp -P main.txt
그게 다야. 그러나 포함된 파일의 이름을 인용해야 합니다.
#include "fragment1.txt"
보너스로 매크로, 조건부 포함 등 C 전처리기의 모든 기능을 사용할 수 있습니다.
답변4
GNU를 사용하면 sed
다음 명령에 이 e
플래그를 사용할 수 있습니다 s
.
sed 's/^#include/cat/e'
#include
로 바꾸고 cat
실행하면 해당 줄이 명령에 대한 응답으로 대체됩니다 cat
.
파일 이름에 공백과 같은 문자가 포함될 수 있는 경우 이를 인용하는 것이 좋습니다.
sed 's/^#include *\(.*\)/cat "\1"/e'
그러나 백슬래시, 틱 및 기타 특수 기능이 있는 파일 이름의 경우에는 여전히 실패할 수 있습니다.