파일에서 필드를 식별해야 하는 요구 사항이 있는데, 필드가 발견되면 새 줄을 추가하고 텍스트를 추가해야 합니다. 하지만 찾은 단어 앞의 공백 수를 계산하여 해당 공백 수에 추가 공백 2개를 더한 뒤에 새 줄을 추가할 수 있도록 하고 싶습니다. 예를 들어
입력 파일:
<tt:abcdef>
.
.
.
</tt:abcdef>
위의 입력 파일에는 이전에 2개의 공백이 있었고 <tt:abcdef>
이 공백을 계산한 다음 아래와 같이 새 줄을 작성하고 싶습니다.
예상 출력 파일:
<tt:abcdef>
<tt:newvar>
.
.
.
</tt:abcdef>
답변1
입력이 표시된 것처럼 간단하고 규칙적이며 xmlstarlet 등을 설치할 수 없거나 설치할 수 없는 경우 모든 Unix 시스템의 모든 쉘에서 awk를 사용할 수 있습니다.
$ awk '{print} sub(/<tt:abcdef>/," "){print $0 "<tt:newvar>"}' file
<tt:abcdef>
<tt:newvar>
.
.
.
</tt:abcdef>
위의 코드는 공백을 계산하지 않고 일치하는 줄에 있는 선행 공백을 재사용합니다. 이는 강력한 것이 아니라 제공한 입력을 제공한 출력으로 변경하기 위한 것입니다. 더 필요한 경우 질문을 편집하여 보다 대표적인 입력/출력 예제와 요구 사항에 대한 더 나은 설명을 제공하십시오.
답변2
사용행복하다(이전 Perl_6)
raku -pe 's/^ (\s+) \<tt\:abcdef\> /{$/}\n$0 <tt:newvar>/;'
또는
raku -pe 's[^ (\s+) \<tt\:abcdef\> ]="{$/}\n$0 <tt:newvar>";'
입력 예:
<tt:abcdef>
.
.
.
</tt:abcdef>
예제 출력:
<tt:abcdef>
<tt:newvar>
.
.
.
</tt:abcdef>
위 내용은 Perl 계열의 프로그래밍 언어인 Raku로 작성된 답변입니다. 즉, -pe
자동 인쇄 한 줄씩 플래그는 전통적인 s///
대체 관용구(두 번째 예에서는 .로 작성됨)를 구현하는 데 사용됩니다 s[…]="…"
.
^ (\s+) \<tt\:abcdef\>
출력에서 인식 순서를 정확하게 재현 해야 하므로 일치하는 변수가 연산자(대체)의 오른쪽 절반 $/
에 포함됩니다 . s///
공백 수가 (\s+)
캡처되어 $0
대체 항목에 다시 추가됩니다. 위의 솔루션은 즉, 코드 블록 내에 표시되지만 $/
실제로 {$/}
는 (귀하의 요청에 따라) 중괄호가 필요하지 않습니다.
위의 방법이 가장 간단한 해결책입니다. 실제로 복잡한 텍스트 파일에서 일치하지 않는 태그를 볼 수 있으므로 태그 쌍 감지를 실제로 고려할 수도 있습니다(더 복잡한 솔루션이 필요함).