![ed(1)로 이 정규식 범위를 인쇄할 수 없는 이유는 무엇입니까?](https://linux55.com/image/227987/ed(1)%EB%A1%9C%20%EC%9D%B4%20%EC%A0%95%EA%B7%9C%EC%8B%9D%20%EB%B2%94%EC%9C%84%EB%A5%BC%20%EC%9D%B8%EC%87%84%ED%95%A0%20%EC%88%98%20%EC%97%86%EB%8A%94%20%EC%9D%B4%EC%9C%A0%EB%8A%94%20%EB%AC%B4%EC%97%87%EC%9E%85%EB%8B%88%EA%B9%8C%3F.png)
ed를 사용하여 이 범위를 인쇄할 수 없는 이유가 완전히 혼란스럽습니다.범위가 2개인 경우-바라보다파일 2.tf파일-;하지만 인쇄할 수 있는 경우는 다음과 같습니다.범위-바라보다파일 1.tf파일 - gsed(macOS에서는 GNU sed) 명령을 사용하여 인쇄할 수 있지만 ed로는 인쇄할 수 없습니다. 내 쉘 세션을 고려하여 내 오해를 명확히 해주십시오.
$ ed -s file1.tf <<<',n'
1 # some comment
2 module "hello_world" {
3 source = "./mydir"
4 }
5 # another comment
$ ed -s file1.tf <<<'/module.*world/,/}/p'
module "hello_world" {
source = "./mydir"
}
$ ed -s file2.tf <<<',n'
1 # some comment
2 module "hello_world" {
3 source = "./mydir"
4 }
5 # another comment
6 # some comment
7 module "hello_again" {
8 source = "./anotherdir"
9 }
10 # another comment
$ ed -s file2.tf <<<'/module.*again/,/}/p'
?
$ gsed -n '/module.*again/,/}/p' file2.tf
module "hello_again" {
source = "./anotherdir"
}
업데이트: 반대 방향이 작동하지만 이유는 모르겠습니다.
$ ed -s file2.tf <<<'?module.*again?,?}?p'
module "hello_again" {
source = "./anotherdir"
}
업데이트 2: 이 ??
방법은 실제로 예상대로 작동하지 않습니다.세 부분그림파일 3.tf파일 예) 설명은 답변을 참조하세요.
$ ed -s file3.tf <<<,n
1 # some comment
2 module "hello_world" {
3 source = "./mydir"
4 }
5 # another comment
6 # some comment
7 module "hello_again" {
8 source = "./anotherdir"
9 }
10 # another comment
11 # some comment
12 module "hello_yet_again" {
13 source = "./yetanotherdir"
14 }
15 # another comment
$ ed -s file3.tf <<<'?module.*hello_again?,?}?p'
module "hello_again" {
source = "./anotherdir"
}
# another comment
# some comment
module "hello_yet_again" {
source = "./yetanotherdir"
}
답변1
문제를 일으키는 와 의 차이점 ed
은 정규식 주소 범위가 처리되는 방식입니다.sed
에서는 sed
먼저 시작 줄을 찾은 다음 끝 줄을 찾을 때까지 모든 줄에 명령이 적용됩니다.
ed
반면에 에서는 범위의 시작 및 끝 선이 현재 행을 기준으로 계산됩니다. 그러면 해당 라인 범위 내의 모든 라인에 명령이 적용됩니다.
/module.*again/, /}/
in 및 두 번째 file 을 사용하는 경우 ed
현재 줄은 파일 끝에 있습니다(방금 버퍼에 로드했기 때문입니다). 범위의 시작 라인은 라인 7로 평가되고 종료 라인은 라인 4(두 번째 표현식과 일치하는 현재 라인 다음의 첫 번째 라인)입니다. 뒤로 실행되는 범위를 가질 수 없으므로 오류가 발생합니다.
를 사용하면 ?module.*again?, ?}?
검색이 반대로 작동하므로 범위의 시작은 이전과 같이 7행으로 계산되지만(한 행만 표현식과 일치함 module.*again
) 이제 범위의 끝은 7보다 큰 9행이므로 같은 질문이 아닙니다.
귀하의 솔루션은아니요?
정규식 구분 기호 대신 in 을 사용하여 검색을 반대로 하면 /
세 부분 중 중간을 올바르게 찾을 수 없습니다(예제에는 두 부분만 있음). 대신 먼저 커서를 범위의 첫 번째 줄로 이동한 다음 해당 줄에서 섹션 끝까지 명령을 적용하세요.
/module.*again/; /}/ p
이는 와 매우 유사해 보이지만 대신 을 /module.*again/, /}/ p
사용하면 시작 주소를 찾을 때까지 끝 주소가 계산되지 않습니다. 이는 다른 선택의 여지가 없기 때문에(전체 문서를 메모리에 저장하지 않음) 범위를 처리하는 기본 방법입니다.;
,
sed
이 표현식은 기본적으로 커서를 범위의 시작 부분으로 명시적으로 이동한 다음 현재 현재 줄에서 섹션 끝까지 명령을 적용하는 더 긴 표현식과 동일합니다.
/module.*again/; ., /}/ p
POSIX 사양ed
,
vs에 대해 말하는 내용은 다음과 같습니다 ;
.
<comma>
,
주소는 ( ) 또는<semicolon>
문자 ( ) 로 구분해야 합니다;
. 구분 기호 가 있는 경우<semicolon>
현재 행(.
)은 두 번째 주소가 계산되기 전에 첫 번째 주소로 설정됩니다. 이 기능은 정방향 및 역방향 검색의 시작선을 결정하는 데 사용할 수 있습니다.