선행 탭 문자(일부 공백 문자 뒤의 탭 문자 포함)만 바꾸는 방법은 무엇입니까?

선행 탭 문자(일부 공백 문자 뒤의 탭 문자 포함)만 바꾸는 방법은 무엇입니까?

탭이나 공백 또는 둘 다로 들여쓰기된 일부 파일이 있습니다. 선행 탭을 공백으로 변환하고 싶습니다(탭 1개를 공백 4개로). 여기에는 일부 선행 공백 뒤의 탭이 포함됩니다. 다음은 입력 라인과 예상 결과의 몇 가지 예입니다.

+----+---+---+
|번호|원래 줄|예상 결과|
+----+---+---+
1 | ␣␣␣␣␣xxx |
2 | ␣␣␣␣␣␣␣xxx |
3 | \t␣\txxx ␣␣␣␣␣␣␣␣␣xxx |
4 | ␣␣␣␣x\txx |
+----+---+---+

expand공백과 탭의 혼합을 처리할 수 없기 때문에 여기서 명령을 사용할 수 없습니다 . 아래는 예시입니다.

user1@ubuntu$ printf "\t  \txxx" | od -t a
0000000  ht  sp  sp  ht   x   x   x
0000007
user1@ubuntu$ printf "\t  \txxx" | expand -i -t 4 | od -t a
0000000  sp  sp  sp  sp  sp  sp  sp  sp   x   x   x
0000013
user1@ubuntu$ 

보시다시피 원래 문자열의 두 공백은 간단히 제거되었습니다. 내 문제를 해결하는 방법? 이 사이트에서 다른 유사한 질문을 읽었지만 내 질문과 완전히 동일하지는 않습니다.

답변1

cat -Tsed를 사용할 수 있습니다( 탭이 표시될 때 파일을 표시하는 데 사용함 ^I).

$ cat -T file
^I abc
^I  ^Ixde^Inot
$ sed ':x;s|^\( *\)\t|\1    |;tx' file | cat -T
     abc
          xde^Inot

불행하게도 as 탭의 해석은 \tPOSIX 사양이 아닌 GNU sed 확장입니다. 그러나 이 문제를 해결할 수 있습니다printfGilles가 설명한 대로 사용하세요.쓰기:

sed ":x;s|^\( *\)$(printf '\t')|\1    |;tx" file

sed는 거기서 무엇을 하고 있나요?

  • s|^\( *\)\t|\1 |

sed가 줄의 시작 부분에 고정된 0개 이상의 공백 문자가 뒤따르는 탭 문자를 찾으면 탭 문자를 4개의 공백으로 대체합니다. 쌍은 \(\)0개 이상의 선행 공백 문자로 구성된 일치 그룹의 발생으로 구분됩니다 \1.

  • tx

대체된 경우 라벨로 이동합니다 :x. 그렇지 않으면 다음 줄로 계속 진행하세요.

답변2

공백이 아닌 첫 번째 문자 앞의 모든 탭 문자를 공백 4개로 바꾸려면 다음을 시도하십시오.

perl -pe '/^(\s+)/; $k=$1; $k=~s/\t/    /g; s/^\s+/$k/'file > newfile

스크립트는 먼저 모든 선행 공백(공백, 탭 및 기타 항목) 을 찾아 $k.$k$k

공백과 탭만 제한하려면 다음을 수행하세요.

perl -pe '/^([ \t]+)/; $k=$1; $k=~s/\t/    /g; s/^\s+/$k/'file > newfile

예제 문자열을 실행하면 이러한 솔루션은 다음을 생성합니다.

$  printf '\t xxx\n   \txxx\n\t \txxx\n\tx\txx\n'  | perl -pe '/^(\s+)/; $k=$1; $k=~s/\t/    /g; s/^\s+/$k/' | od -t a
0000000  sp  sp  sp  sp  sp   x   x   x  nl  sp  sp  sp  sp  sp  sp  sp
0000020   x   x   x  nl  sp  sp  sp  sp  sp  sp  sp  sp  sp   x   x   x
0000040  nl  sp  sp  sp  sp   x  ht   x   x  nl
0000052

관련 정보