sed는 4 개의 공백을 2로 변환


14

어떻게 4 개의 공백을 2 개의 공백으로 변환 sed합니까? 가능합니까?

이것을 찾았지만 탭을 공백으로 변환합니다.

sed -r ':f; s|^(\t*)\s{4}|\1\t|g; t f' file

답변:


13

게시 한 스크립트는 4 * n 공백을 탭이 앞에있는 경우에만 4 개의 n 공백을 n 개의 탭으로 변환합니다.

4 개의 공백을 2 개의 공백으로 바꾸고 만 들여 쓰기 만하고 sed로 할 수는 있지만 대신 Perl을 권장합니다.

perl -pe 's{^((?: {4})*)}{" " x (2*length($1)/4)}e' file

sed에서 :

sed -e 's/^/~/' -e ': r' -e 's/^\( *\)~    /\1  ~/' -e 't r' -e 's/~//' file

indent대신 사용할 수 있습니다 .


나는Nested quantifiers in regex; marked by <-- HERE in m/^( {4}* <-- HERE )/ at -e line 1.
eddygeek

1
@eddygeek 아, 그리고 그와 다른 몇 가지 버그. gobbledygook을 실제 펄 코드로 대체했습니다.
Gilles 'SO- 악마 그만'

5

간단한 방법으로 작동하지 않습니다.

sed -r 's/ {4}/  /g'

그렇지 않은 경우 실패한 곳에 입력을 게시하십시오.


1
이것은 줄의 시작 부분으로 되돌아 가지 않습니다. 거기에 고정하면 여러 경기에서 작동하지 않습니다. 그래서 우리는 아래 unix.stackexchange.com/a/375200/259620에 있습니다.
geek-merlin

2 개의 공백과 4 개의 공백이 조합 된 경우에는 작동하지 않습니다. 2 개의 들여 쓰기는 4 개로 계산되기 때문입니다.
Matt Fletcher

@aexl : OP의 요구 사항이 아닙니다
Thor

@ mattfletcher : 문제는 4 개의 공백을 2로 바꾸는 것에 관한 것이 었습니다. 그래서 당신의 요점을 보지 못합니다
Thor

4

선행 공백 만 변환해야하는 경우 :

sed 'h;s/[^ ].*//;s/    /  /g;G;s/\n *//'

의견 :

sed '
  h; # save a copy of the pattern space (filled with the current line)
     # onto the hold space
  s/[^ ].*//; # remove everything starting with the first non-space
              # from the pattern space. That leaves the leading space
              # characters
  s/    /  /g; # substitute every sequence of 4 spaces with 2.
  G; # append a newline and the hold space (the saved original line) to
     # the pattern space.
  s/\n *//; # remove that newline and the indentation of the original
            # line that follows it'

또한 vim의 'ts'설정과 :retab명령을보십시오


vim 솔루션을 사용하면 vim으로 여러 파일을 일괄 편집하는 방법이 있습니까? 그렇지 않으면 매크로를 만들어야한다고 생각합니까?
chrisjlee

참고 'ts':retab문제에 대한 해결책이 아니라 관련되어 있으며 주소 전체 목표를 도움이 될 수 있습니다. 당신은 할 수있는 vim -- *.c, :set ts=...그리고 :argdo retab:argdo retab!. 'sw'옵션 및 vim 자체 들여 쓰기 기능 도 참조하십시오 .
Stéphane Chazelas

2
sed 's/^\( \+\)\1\1\1/\1\1/' file

선행 공백을 동일한 그룹의 4 개의 인스턴스로 나누고 (모두 동일) 그룹의 두 인스턴스로만 교체합니다.


이것이 기존 솔루션을 어떻게 개선합니까?
Philippos

1
홀수 공간을 유지하고 선행 공백에만 영향을 미치며 전역 플래그가 필요하지 않으며 교체의 양쪽에있는 공간 (또는 탭)을 처리하기 위해 쉽게 조정할 수 있으며 더 복잡한 sed 명령을 사용하지 않습니다. 더 많은 일반 사용자에게 적합하지 않을 수 있습니다. 많은 것들과 마찬가지로, 그것이 개선인지 여부는 꽤 주관적이지만 나 자신을 위해 말하기 : 스크립트에서 이것을 찾는 것이 나열된 다른 솔루션 중 일부보다 훨씬 더 빨리 이해하는 것이 훨씬 쉽습니다.
Mal

흥미 롭군 다행이다. 일반적으로 역 참조는 글로벌 플래그가 아닌 악으로 간주됩니다. 그러나 더 편리한 스크립트 (피하기 \+)를 사용하여 동일한 것을 쉽게 달성 할 수 있습니다 . 감사합니다.
Philippos

1
sed 's/    \{2,4\}\( \{0,1\}[^ ].*\)*/  \1/g' <input

그것은 일련의 공백을 쥐어 짜야합니다.

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.