선행 탭을 4개의 공백으로 sed로 어떻게 바꾸나요?

선행 탭을 4개의 공백으로 sed로 어떻게 바꾸나요?

vim에서는 다음과 같이 하는 것이 가능할 것 같습니다:

:s/^\t\+/\=repeat('    ',len(submatch(0)))

이것이 sed로 어떻게 변환되는지는 알지 못했습니다. 나는 다음을 시도했다 :

sed -ri "s/^\t\+/\=repeat('    ',len(submatch(0)))/g" test.txt

명령이 효과가 없는 것 같습니다.

답변1

이것은 예 expand를 들어 expand -t 4 file.txt.

expand원본 파일을 편집하지는 않지만 새 파일로 리디렉션하여 mv원본 위에 놓을 수 있습니다. 또는 sponge설치된 경우 사용할 수 있습니다. 예:

    expand -t 4 file.txt > file.new && mv file.new file.txt
or 
    expand -t 4 file.txt | sponge file.txt

참고로, unexpand반대로 여러 공백을 탭으로 변환하는 방법을 참조하세요.

expand및 둘 다 unexpand고정 너비 탭(예 : -t 4또는 -t 8등) 사용을 지원합니다.또는탭 위치 목록(예 -t 4,12,32: ) 또한 초기, 선행 공백/탭만 변환하는 옵션도 있습니다. 자세한 내용은 매뉴얼 페이지를 참조하십시오.


에 대한 자세한 내용은 및를 sponge참조하세요 .man sponge파일을 자체적으로 파이프하는 스폰지에 대한 표준 대안이 있습니까?. 즉, 임시 파일을 사용하여 리디렉션 및 mv를 수행합니다. 그런데, stdout을 현재 stdin으로 사용 중인 동일한 파일로 리디렉션하지 마십시오. 쉘은 읽기도 전에 이를 덮어씁니다.

sponge출신이다더 많은 유틸리티패키지.


추신: 또한 참조하십시오GNU 들여쓰기또는 다른 유사한 소스 코드 재형식 지정 도구 중 하나입니다.

답변2

$ cat -T /tmp/test.txt
^I^I^I3^I<= this final tab should remain
^I^I2
^I1

sed 사용:

sed ':loop;s/^\( *\)\t/\1    /;tloop' /tmp/test.txt | cat -T
            3^I<= this final tab should remain
        2
    1

loop위의 내용은 모든 선행 공백과 선행 탭을 캡처하는 루프(아이러니하게도 레이블이 지정됨)를 설정합니다 . 공백을 대체하고 탭을 4개의 공백으로 변환합니다. 성공하면( t) 루프로 다시 분기됩니다. 보다https://stackoverflow.com/a/35017207/493161

관련 정보