sed: 선행 탭을 그대로 유지하면서 문자열 사이의 초과 공백을 단일 공백으로 제거합니다.

sed: 선행 탭을 그대로 유지하면서 문자열 사이의 초과 공백을 단일 공백으로 제거합니다.

나는 코드를 가지고있다:

1 /**             
2 a        b         c
3 **/
4 int main() {
5     int x;
6     if ( condition) {
7     return       x;
8     }
9 }

7행처럼 토큰이나 문자열 사이의 여러 공백을 단일 공백으로 변경해야 하지만 주석(2행)이나 코드의 선행 탭은 영향을 받아서는 안 됩니다. 따라서 출력은 다음과 같아야 합니다.

1 /**             
2 a        b         c
3 **/
4 int main() {
5     int x;
6     if ( condition) {
7     return x;
8     }
9 }

'tr'을 사용해 보았지만 ~$ tr -s " " < file2행이 변경되고 5~8행에서 선행 탭 문자가 제거되었습니다. 을 사용하여 수행할 수 있습니까 sed?

답변1

얼마나 멀리 갈 것인가?

sed -rn '\#/\*\*#,\#\*\/*# {p;b}; s/([^ ]) +/\1 /g; p' file

이해합니다? 수정되지 않은 주석 줄을 인쇄하고(그러나 같은 줄의 주석 켜기/끄기를 처리할 수 없음) 스크립트의 나머지 부분을 건너뜁니다. 주석 처리되지 않은 줄의 경우 공백이 아닌 문자 뒤에 오는 여러 공백(따라서 범위를 벗어난 줄 들여쓰기)을 단일 공백으로 압축합니다.

답변2

마지막으로 이것은 나에게 효과적이었습니다.

sed -i 's/\([a-zA-Z]\+\)\( *\)\([a-zA-Z]\+\)/\1 \3/g' $1

답변3

사용행복하다(이전 Perl_6)

~$ raku -pe 's/^ [\d+ " "?] \t* \H+? <(" " ** 2..*)> / /;'  file

#OR

~$ raku -pe 's/^ [\d+ " "?] \c[TAB]* \H+? <(\c[SPACE] ** 2..*)> / /;'  file

위의 Raku 코드는 문자 그대로 탭( \tor ) \c[TAB]과 공백( " "or \c[SPACE])을 구분합니다.

이러한 -pe플래그는 자동 인쇄 기능을 사용하여 입력에서 코드를 한 줄씩 실행합니다. 정규식은 ^문자열의 시작 부분부터 숫자를 검색하고 [\d+ " "?]그 뒤에 0 또는 1개의 공백, 그 뒤에 선택적 탭 문자, 그 뒤에 (탐욕스럽지 않게) \H+?하나 이상의 수평이 아닌 공백 문자, 마지막으로 2..*2개 이상의 공백을 검색합니다. . <(...캡처 )>태그는 단일 공백으로 대체되는 마지막 두 개 이상의 공백을 제외하고 일치하는 모든 항목을 제거합니다.

[\d+ " "?]줄 번호가 없으면 대괄호로 묶인 그룹이 생략됩니다. 한 줄에 하나만 바꾸기 때문에 줄 오른쪽 끝에 공백 문자가 여러 개 있으면 여러 번 실행해야 할 수도 있습니다.

입력 예:

1 /**             
2 a\tb\tc
3 **/
4 int main() {
5\tint x;
6\tif ( condition) {
7\treturn       x;
8\t}
9 }

예제 출력:

1 /** 
2 a\tb\tc
3 **/
4 int main() {
5\tint x;
6\tif ( condition) {
7\treturn x;
8\t}
9 }

물론 위의 답변은 주석 블록의 문자가 여러 공백이 아닌 탭으로 구분되는 것을 기반으로 합니다. 아마도 가장 좋은 방법은저것이다사전 실행특히 주석 블록을 바꾸십시오.

~$ raku -pe 'state $ph;                     \
             $ph = 1 if /^  "/**"  \s* $/;  \
             $ph = 0 if /^  "**/"  \s* $/;  \
             s:g/" " ** 4/\t/ if  $ph == 1 ;'   file

위 코드는 주석 블록 내에서만 4개의 ​​공백을 탭 문자로 대체합니다. 각 줄이 줄 번호로 시작하는 경우 [\d+ " "?]두 번째 및 세 번째 문의 대괄호 그룹에 다시 추가하세요.^

https://unix.stackexchange.com/a/701572/227738
https://docs.raku.org/언어/regexes
https://raku.org

관련 정보