디렉토리의 모든 파일에서 탭을 공백으로 변환하는 방법은 무엇입니까?


251

디렉토리의 모든 파일에서 탭을 공백으로 변환하려면 어떻게해야합니까 (재귀 적으로)?

또한 탭당 공백 수를 설정하는 방법이 있습니까?


파일 또는 파일 이름의 탭을 바꾸시겠습니까?
cppcoder 2018 년

3
pr이를위한 훌륭한 유틸리티입니다. 이 답변을 참조하십시오 .
codeforester 2018 년

답변:


69

경고 : 이렇게하면 저장소가 손상됩니다.

손상됩니다 바이너리 파일 들에서 포함 svn, .git! 사용하기 전에 의견을 읽으십시오!

find . -iname '*.java' -type f -exec sed -i.orig 's/\t/ /g' {} +

원본 파일은로 저장됩니다 [filename].orig.

'* .java'를 찾고있는 파일 유형의 파일 끝으로 바꾸십시오. 이렇게하면 실수로 이진 파일이 손상되는 것을 방지 할 수 있습니다.

단점 :

  • 파일의 모든 곳에서 탭을 대체합니다.
  • 이 디렉토리에 5GB SQL 덤프가 있으면 시간이 오래 걸립니다.

12
탭과 공백이 혼합 된 시각적 공간의 경우이 방법으로 확장 할 수 없습니다.
피자

7
예를 들어 .php 파일에 대해서만 파일 매처를 추가합니다. ./ -iname "* .php"-type f -exec sed -i 's / \ t / / g'{} \;
Daniel Luca Clean 유니콘

98
SED를 사용하지 마십시오! 문자열에 포함 된 탭이 있으면 코드가 엉망이 될 수 있습니다. 이것이 확장 명령이 다루어야 할 것입니다. 사용하십시오 expand.
David W.

5
@DavidW. 줄 시작 부분에서 탭만 바꾸려면이 명령을 업데이트하면됩니다. find ./ -type f -exec sed -i 's/^\t/####/g' {} \;. 그러나 expand 명령을 알지 못했습니다. 매우 유용합니다!
Martin Konecny

29
사용하지 마세요! 이 답변은 또한 로컬 git 저장소를 망쳤습니다. 탭과 공백이 혼합 된 파일이 있으면 일련의 #이 삽입됩니다. 대신 Gene의 답변 또는 Doge의 의견을 대신 사용하십시오.
꼭두각시

344

간단한 교체 sed는 가능하지만 최상의 솔루션은 아닙니다. 탭 사이에 "추가"공간이 있으면 교체 후에도 여백이 그대로 유지되므로 여백이 고르지 않게됩니다. 줄 중간에 확장 된 탭도 제대로 작동하지 않습니다. 에서 bash대신 말할 수 있습니다.

find . -name '*.java' ! -type d -exec bash -c 'expand -t 4 "$0" > /tmp/e && mv /tmp/e "$0"' {} \;

expand현재 디렉토리 트리의 모든 Java 파일에 적용 합니다. -name다른 파일 형식을 대상으로하는 경우 인수를 제거 / 바꾸십시오 . 주석 중 하나에서 언급했듯이 -name약한 와일드 카드를 제거 하거나 사용할 때 매우주의하십시오 . 의도없이 리포지토리 및 기타 숨겨진 파일을 쉽게 클로버 할 수 있습니다. 이것이 원래 답변에 다음이 포함 된 이유입니다.

무언가 잘못 될 경우를 대비하여 이와 같은 것을 시도하기 전에 항상 트리의 백업 사본을 만들어야합니다.


2
@JeffreyMartinez 좋은 질문입니다. gniourf_gniourf는 11 월 11 일에 원래의 답변을 편집하고 올바른 사용법을 모르는 것에 대해 비난하는 말을했습니다 {}. 그가 $0언제 -c사용 되는지 알지 못하는 것 같습니다 . 그런 다음 dimo414가 변환 디렉토리에서 temp 사용 에서에서 다른 마운트 포인트에있는 /tmp경우 훨씬 느려질 /tmp것으로 변경되었습니다. 불행히도 귀하의 $0제안 을 테스트 할 Linux 박스가 없습니다 . 그러나 나는 당신이 맞다고 생각합니다.
유전자

1
@Gene은 명확하게 해 주셔서 감사합니다. 스택 오버 플로우 좋아 : p. 그래도 내가 * .java를 올바르게 이스케이프하려면 '* .java'주위에 따옴표를 사용해야한다고 덧붙일 것입니다.
Jeffrey Martinez

2
누군가 find에서 '알 수없는 기본 또는 연산자'오류가 발생하면 여기를 수정하는 전체 명령이 있습니다.find . -name '*.java' ! -type d -exec bash -c 'expand -t 4 "$0" > /tmp/e && mv /tmp/e "$0"' {} \;
Doge

4
이 답변에 대한 의견이 충분하지 않다고 생각했기 때문에 이것이 내 의견입니다. joeyh.name/code/moreutilssponge 에서 사용하면 다음 과 같이 작성할 수 있습니다.find . -name '*.py' ! -type d -exec bash -c 'expand -t 8 "$0" | sponge "$0"' {} \;
tokland

8
멍청하고 사용하지 마십시오. find . -name '*'방금 로컬 git repo를 파괴했습니다
Gautam

193

명령 행 도구를 사용해보십시오 expand.

expand -i -t 4 input | sponge output

어디

마지막으로 Homebrew ( )로 gexpand설치 한 후 OSX에서 사용할 수 있습니다 .coreutilsbrew install coreutils



32
당신은 통과해야 -i하는 expand각 줄에 선도적 인 탭을 대체 할 수 있습니다. 이렇게하면 코드의 일부일 수있는 탭을 교체하지 않아도됩니다.
Quolonel Questions

10
디렉토리의 모든 단일 파일에 대해 재귀 적으로 어떻습니까?
ahnbizcad 2016 년

4
이것을 사용하려고 할 때마다 파일의 일부 (보통 모두)를 비 웁니다. : \
ThorSummoner 2016 년

5
@ThorSummoner : bash input와 동일한 파일 인 output경우 시작하기 전에 bash가 내용을 클로버 expand합니다. 이것이 >작동 하는 방식입니다.
Robert Siemer

34

지금까지 최고의 솔루션 인 Gene의 답변 에서 최고의 의견을 수집하는 것은 moreutils 을 사용 sponge하는 입니다.

sudo apt-get install moreutils
# The complete one-liner:
find ./ -iname '*.java' -type f -exec bash -c 'expand -t 4 "$0" | sponge "$0"' {} \;

설명:

  • ./ 현재 디렉토리에서 재귀 적으로 검색 중입니다.
  • -iname사례를 구분 일치는 (모두입니다 *.java*.JAVA좋아하는)
  • type -f 일반 파일 만 찾습니다 (디렉토리, 이진 또는 심볼릭 링크 없음)
  • -exec bash -c 각 파일 이름에 대해 서브 쉘에서 다음 명령을 실행하십시오. {}
  • expand -t 4 모든 TAB을 4 칸으로 확장
  • sponge표준 입력 (에서 expand)을 흡수하고 파일 (같은 파일)에 씁니다. *.

참고 : * 간단한 파일 리디렉션 ( > "$0")은 파일을 너무 빨리 덮어 쓰기 때문에 여기서 작동하지 않습니다 .

장점 : 모든 원본 파일 권한이 유지되고 중간 tmp파일이 사용 되지 않습니다 .


2
TIL : 15 년 동안 Linux를 사용한 후 놀라운 스폰지 명령. 인터넷에서 당신에게 신비한 기사 감사합니다.
sscarduzio

19

백 슬래시로 이스케이프 처리하십시오 sed.

리눅스에서 :

  • 모든 * .txt 파일에서 모든 탭을 1 개의 하이픈 대신 사용하십시오.

    sed -i $'s/\t/-/g' *.txt
  • 모든 * .txt 파일에서 모든 탭을 1 개의 공백으로 바꿉니다.

    sed -i $'s/\t/ /g' *.txt
  • 모든 * .txt 파일에서 모든 탭을 4 개의 공백으로 바꾸십시오.

    sed -i $'s/\t/    /g' *.txt

Mac에서 :

  • 모든 * .txt 파일에서 모든 탭을 4 개의 공백으로 바꾸십시오.

    sed -i '' $'s/\t/    /g' *.txt

2
@ Машаsed -i '' $'s/\t/ /g' $(find . -name "*.txt")
xyzale

이 답변은 가장 간단한 것 같습니다.
Yan King Yin

6

일반적으로 사용 가능한 pr명령 (man page here )을 사용할 수 있습니다 . 예를 들어, 탭을 4 개의 공백으로 변환하려면 다음을 수행하십시오.

pr -t -e=4 file > file.expanded
  • -t 헤더를 억제
  • -e=num탭을 num공백으로 확장

바이너리 파일을 건너 뛰면서 디렉토리 트리의 모든 파일을 재귀 적으로 변환하려면 :

#!/bin/bash
num=4
shopt -s globstar nullglob
for f in **/*; do
  [[ -f "$f" ]]   || continue # skip if not a regular file
  ! grep -qI "$f" && continue # skip binary files
  pr -t -e=$num "$f" > "$f.expanded.$$" && mv "$f.expanded.$$" "$f"
done

이진 파일을 건너 뛰는 논리는 이 게시물 에서 나온 입니다.

노트:

  1. 이것을하는 것은 자식이나 svn repo에서 위험 할 수 있습니다
  2. 문자열 리터럴에 탭이 포함 된 코드 파일이있는 경우 올바른 솔루션이 아닙니다.

1
expand둘 다 POSIX라는 점에서 어떤 이점 이 있습니까? 예를 들어 인라인 변경 옵션이 있습니까? 힘내 안전 : stackoverflow.com/a/52136507/895245
Ciro Santilli 郝海东 冠状 病 六四 事件 法轮功

5

디렉토리의 모든 파일에서 탭을 공백으로 변환하려면 어떻게해야합니까 (재귀 적으로)?

이것은 일반적으로 원하는 것이 아닙니다 .

png 이미지에 대해이 작업을 수행 하시겠습니까? PDF 파일? .git 디렉토리? 당신의 Makefile( 필요한 탭 합니까)? 5GB SQL 덤프?

이론적으로는 많은 exlude 옵션을 전달할 수 있습니다. find 당신이 사용하는 다른 . 그러나 이것은 깨지기 쉽고 다른 바이너리 파일을 추가하자마자 깨질 것입니다.

당신이 원하는 것은 최소한 :

  1. 특정 크기 이상의 파일을 건너 뜁니다.
  2. NULL 바이트가 있는지 확인하여 파일이 이진인지 감지합니다.
  3. 파일 의 시작 부분 에서만 탭을 교체 하십시오 ( expand그렇지 만 sed 그렇지 않습니다).

내가 아는 한,이 작업을 수행 할 수있는 "표준"유닉스 유틸리티가 없으며, 쉘 one-liner로 수행하기가 쉽지 않으므로 스크립트가 필요합니다.

얼마 전에 나는 정확히 그렇게하는 sanitize_files 라는 작은 스크립트를 만들었습니다 . 또한로 대체 , 후행 추가 \r\n와 같은 다른 일반적인 사항을 수정합니다.\n\n

아래에 추가 기능과 명령 줄 인수가 없는 간단한 스크립트 찾을 수 있지만이 스크립트는 버그 수정 및이 게시물 이외의 다른 업데이트를받을 가능성이 높으므로 위의 스크립트를 사용하는 것이 좋습니다.

쉘 대체 (globbing)을 사용하는 것을 나는 또한처럼, 여기에 다른 몇 가지 답변에 대한 응답으로 지적하는 것 아니 이 일을 강력한 방법은 조만간 당신이 맞는 것보다 더 많은 파일로 끝날 것이기 때문에, ARG_MAX현대에 ( Linux 시스템은 128k이므로 많이 보일지 모르지만 조만간 충분 하지 않습니다 .


#!/usr/bin/env python
#
# http://code.arp242.net/sanitize_files
#

import os, re, sys


def is_binary(data):
    return data.find(b'\000') >= 0


def should_ignore(path):
    keep = [
        # VCS systems
        '.git/', '.hg/' '.svn/' 'CVS/',

        # These files have significant whitespace/tabs, and cannot be edited
        # safely
        # TODO: there are probably more of these files..
        'Makefile', 'BSDmakefile', 'GNUmakefile', 'Gemfile.lock'
    ]

    for k in keep:
        if '/%s' % k in path:
            return True
    return False


def run(files):
    indent_find = b'\t'
    indent_replace = b'    ' * indent_width

    for f in files:
        if should_ignore(f):
            print('Ignoring %s' % f)
            continue

        try:
            size = os.stat(f).st_size
        # Unresolvable symlink, just ignore those
        except FileNotFoundError as exc:
            print('%s is unresolvable, skipping (%s)' % (f, exc))
            continue

        if size == 0: continue
        if size > 1024 ** 2:
            print("Skipping `%s' because it's over 1MiB" % f)
            continue

        try:
            data = open(f, 'rb').read()
        except (OSError, PermissionError) as exc:
            print("Error: Unable to read `%s': %s" % (f, exc))
            continue

        if is_binary(data):
            print("Skipping `%s' because it looks binary" % f)
            continue

        data = data.split(b'\n')

        fixed_indent = False
        for i, line in enumerate(data):
            # Fix indentation
            repl_count = 0
            while line.startswith(indent_find):
                fixed_indent = True
                repl_count += 1
                line = line.replace(indent_find, b'', 1)

            if repl_count > 0:
                line = indent_replace * repl_count + line

        data = list(filter(lambda x: x is not None, data))

        try:
            open(f, 'wb').write(b'\n'.join(data))
        except (OSError, PermissionError) as exc:
            print("Error: Unable to write to `%s': %s" % (f, exc))


if __name__ == '__main__':
    allfiles = []
    for root, dirs, files in os.walk(os.getcwd()):
        for f in files:
            p = '%s/%s' % (root, f)
            if do_add:
                allfiles.append(p)

    run(allfiles)


5

재귀 응용 프로그램에 대한 위의 "찾기"예를 좋아합니다. 현재 디렉토리에서 와일드 카드와 일치하는 파일 만 변경하여 비재 귀적으로 적용하려면 소량의 파일에 대해 쉘 글로브 확장으로 충분할 수 있습니다.

ls *.java | awk '{print "expand -t 4 ", $0, " > /tmp/e; mv /tmp/e ", $0}' | sh -v

당신이 작동 신뢰 후에 당신이 침묵하려는 경우, 그냥 드롭 -vsh끝에 명령.

물론 첫 번째 명령에서 파일 세트를 선택할 수 있습니다. 예를 들어, 다음과 같이 제어 된 방식으로 특정 서브 디렉토리 (또는 디렉토리) 만 나열하십시오.

ls mod/*/*.php | awk '{print "expand -t 4 ", $0, " > /tmp/e; mv /tmp/e ", $0}' | sh

또는 깊이 매개 변수 등을 조합하여 find (1)를 실행하십시오.

find mod/ -name '*.php' -mindepth 1 -maxdepth 2 | awk '{print "expand -t 4 ", $0, " > /tmp/e; mv /tmp/e ", $0}' | sh

1
파일 이름의 총 ARG_MAX길이 는 길이 만 가능하기 때문에 쉘 글 로빙은 조만간 중단됩니다 . 이것은 Linux 시스템에서 128k이지만 셸 globbing에 의존하지 않을 정도로이 한계에 도달했습니다.
Martin Tournoij

1
실제로 적용 할 필요는 없습니다. find알 수 있으며 -maxdepth 1전체 트리가 아닌 수정중인 디렉토리의 항목 만 처리합니다.
ShadowRanger

4

내가 사용하는 astyle혼합 탭과 공백을 찾은 후 다시 들여 쓰기 내 모든 C / C ++ 코드. 원하는 경우 특정 버팀대 스타일을 적용하는 옵션도 있습니다.


4

vim그것을 위해 사용할 수 있습니다 :

find -type f \( -name '*.css' -o -name '*.html' -o -name '*.js' -o -name '*.php' \) -execdir vim -c retab -c wq {} \;

Carpetsmoker가 말했듯이 vim설정 에 따라 다시 탭됩니다 . 그리고 파일에 모델이 있다면. 또한 줄의 시작 부분뿐만 아니라 탭을 대체합니다. 일반적으로 원하는 것이 아닙니다. 예를 들어 탭이 포함 된 리터럴이있을 수 있습니다.


:retab시작시 탭이 아닌 파일의 모든 탭을 변경합니다. 또한 vimrc 또는 modeline의 설정 :tabstop:expandtab설정 에 따라 다르 므로 전혀 작동하지 않을 수 있습니다.
Martin Tournoij

@Carpetsmoker 줄의 시작 부분에 탭에 대한 좋은 지적. 여기에 어떤 해결책이이 경우를 처리합니까? 에 관해서 tabstopexpandtab설정, 당신이 사용하는 경우 밖으로 작동합니다 vim. 파일에 모드 행이없는 한.
x-yuri

@ x-yuri 좋은 질문이지만 일반적으로 무질서합니다. 대부분의 사람들은 리터럴에서 \ t 실제 탭을 사용하지 않습니다.
Ricardo Cruz

4

내 권장 사항은 다음을 사용하는 것입니다.

find . -name '*.lua' -exec ex '+%s/\t/  /g' -cwq {} \;

코멘트:

  1. 현장 편집에 사용하십시오. VCS에 백업을 유지하십시오. * .orig 파일을 생성 할 필요가 없습니다. 어쨌든 이것이 예상대로 작동하는지 확인하기 위해 마지막 커밋과 결과를 비교하는 것이 좋습니다.
  2. sed스트림 편집기입니다. ex현장 편집에 사용 합니다. 이렇게하면 맨 위 답변 에서와 같이 각 대체 파일에 대해 임시 파일과 생성 셸이 생성되지 않습니다 됩니다.
  3. 경고 : 들여 쓰기에 사용 된 탭뿐만 아니라 모든 탭이 지저분합니다. 또한 컨텍스트 인식 탭 교체를 수행하지 않습니다. 이것은 내 유스 케이스에 충분했습니다. 그러나 당신에게 받아 들여지지 않을 수도 있습니다.
  4. 편집 :이 답변의 이전 버전 find|xargs대신에 사용 되었습니다 find -exec. @ gniourf-gniourf가 지적한 것처럼 파일 이름 cf에 공백, 따옴표 및 제어 문자에 문제가 발생합니다. 휠러 .

ex모든 유닉스 시스템에서 사용 가능한 것은 아닙니다. 이를 대체하면 vi -e더 많은 시스템에서 작동 할 수 있습니다. 또한 정규 표현식은 여러 개의 시작 탭 문자를 두 개의 공백으로 바꿉니다. +%s/\t/ /g다단계 들여 쓰기를 제거하지 않기 위해 정규식을 바꾸십시오. 그러나 이것은 들여 쓰기에 사용되지 않는 탭 문자에도 영향을줍니다.
Lukas Schmelzeisen

ex는 POSIX [1]의 일부이므로 사용 가능해야합니다. 다단계 indendation에 대한 좋은 지적. 필자는 실제로 /\t/ /파일 에서 변형을 사용 했지만 /\t\+//들여 쓰기가 아닌 탭을 나누지 않기로 선택했습니다 . 다중 들여 쓰기와 관련된 문제를 놓쳤습니다! 답변 업데이트. [1] man7.org/linux/man-pages/man1/ex.1p.html#SEE%C2%A0ALSO
Heinrich Hartmann

2
xargs이 방법으로 사용 하는 것은 쓸모없고 비효율적이며 깨집니다 (공백 또는 따옴표가 포함 된 파일 이름을 생각하십시오). 왜 사용하지 find-exec대신 스위치를?
gniourf_gniourf

공백과 따옴표가있는 파일 이름이 손상되었다고 주장합니다. ) 당신이 지원하기로 선택 해야하는 경우 : -print0옵션 찾기 / xargs. 나는 xargs를 좋아한다 -exec. a) 우려의 분리 b) GNU 병렬로보다 쉽게 ​​교체 될 수있다.
Heinrich Hartmann

@gniourf_gniourf 의견을 추가하여 업데이트했습니다.
Heinrich Hartmann

4

디렉토리 대신 모든 Java 파일을 재귀 적으로 변환하여 탭 대신 4 개의 공백을 사용하려면 다음을 수행하십시오.

find . -type f -name *.java -exec bash -c 'expand -t 4 {} > /tmp/stuff;mv /tmp/stuff {}' \;

어떻게에서이 응답 다릅니다 3 년 전 게시 된?
PP

2
당신의 대답도 마찬가지입니다. 사실, 이것은 Gene의 대답보다 열등한 버전입니다. 1) Gene의 대답은 같은 이름의 디렉토리를 처리합니다. 2) 확장에 실패하면 움직이지 않습니다 .
PP

4

이를 위해 패키지 find와 함께 사용할 수 있습니다 tabs-to-spaces.

먼저 설치 tabs-to-spaces

npm install -g tabs-to-spaces

그런 다음 프로젝트의 루트 디렉토리에서이 명령을 실행하십시오.

find . -name '*' -exec t2s --spaces 2 {} \;

이것은 모든 대체 할 tab2 문자를 spaces각 파일에.


3

시체가 언급되지 않았 rpl습니까? rpl을 사용하면 모든 문자열을 바꿀 수 있습니다. 탭을 공백으로 변환하려면

rpl -R -e "\t" "    "  .

매우 간단합니다.


1
이로 인해 내 리포지토리의 모든 이진 파일이 손상되었습니다.
Aaron Franke

1
훌륭한 명령이지만 위에 지정된 폴더의 재귀 파일 및 모든 파일 옵션으로 위험 할 수 있습니다. --dry-run 옵션을 "경우에 따라"추가하여 올바른 폴더에 앉아 있는지 확인합니다.
MortimerCat

2

사용 expand다른 답변에서 제안 된대로 것이이 작업에만 가장 논리적 인 접근법으로 보입니다.

즉, Bash 및 Awk를 사용하여 다른 수정을 수행 할 수도 있습니다.

Bash 4.0 이상을 사용하는 경우 shopt 내장 globstar 을 사용 하여을 재귀 적으로 검색 할 수 있습니다 **.

GNU Awk 버전 4.1 이상에서는 "inplace"파일과 같은 sed를 만들 수 있습니다.

shopt -s globstar
gawk -i inplace '{gsub("\t","    ")}1' **/*.ext

탭당 공백 수를 설정하려는 경우 :

gawk -i inplace -v n=4 'BEGIN{for(i=1;i<=n;i++) c=c" "}{gsub("\t",c)}1' **/*.ext

2

다음 스크립트를 다운로드하여 실행하여 일반 텍스트 파일에서 하드 탭을 소프트 탭으로 재귀 적으로 변환하십시오.

일반 텍스트 파일이 들어있는 폴더 내에서 스크립트를 실행하십시오.

#!/bin/bash

find . -type f -and -not -path './.git/*' -exec grep -Iq . {} \; -and -print | while read -r file; do {
    echo "Converting... "$file"";
    data=$(expand --initial -t 4 "$file");
    rm "$file";
    echo "$data" > "$file";
}; done;

2

힘내 저장소 친화적 인 방법

git-tab-to-space() (
  d="$(mktemp -d)"
  git grep --cached -Il '' | grep -E "${1:-.}" | \
    xargs -I'{}' bash -c '\
    f="${1}/f" \
    && expand -t 4 "$0" > "$f" && \
    chmod --reference="$0" "$f" && \
    mv "$f" "$0"' \
    '{}' "$d" \
  ;
  rmdir "$d"
)

현재 디렉토리 아래의 모든 파일에서 작동하십시오.

git-tab-to-space

C 또는 C ++ 파일에서만 작동합니다.

git-tab-to-space '\.(c|h)(|pp)$'

탭이 필요한 성가신 Makefile 때문에 특히 이것을 원할 것입니다.

명령 git grep --cached -Il '':

  • 추적 된 파일 만 나열하므로 그 안에는 아무것도 없습니다 .git
  • 디렉토리, 이진 파일 (손상) 및 심볼릭 링크 (일반 파일로 변환)를 제외합니다

설명 : git 저장소에 모든 텍스트 (이진이 아닌) 파일을 나열하는 방법은 무엇입니까?

chmod --reference파일 권한을 변경하지 않고 유지합니다 : /unix/20645/clone-ownership-and-permissions-from-another-file 불행히도 간결한 POSIX 대안을 찾을 수 없습니다 .

코드베이스에 기능적인 원시 탭을 문자열로 허용하려는 아이디어가 있다면 다음을 사용하십시오.

expand -i

그런 다음 시작하지 않은 모든 라인 탭을 하나씩 차례로 살펴보면 다음과 같이 나열 할 수 있습니다 .

우분투 18.04에서 테스트되었습니다.


-1

".lua"파일에서 탭을 공백으로 변환 [탭-> 2 공백]

find . -iname "*.lua" -exec sed -i "s#\t#  #g" '{}' \;

분명히 탭이 확장되는 공간의 양은 상황에 따라 다릅니다. 따라서 sed는 작업에 완전히 부적절한 도구입니다.
Sven

?? @Sven, 내 sed 명령은 확장 명령과 동일한 기능을 수행합니다 ( expand -t 4 input >output)
Makah

3
당연히 아니지. expand -t 4a\tb을 3 칸으로 확장하고 탭 aa\tb을 2 칸으로 확장합니다 . expand탭의 컨텍스트를 고려 sed하고 컨텍스트와 상관없이 탭을 지정한 공백의 양으로 대체하지 않습니다.
Sven

-1

vim-way를 사용하십시오 :

$ ex +'bufdo retab' -cxa **/*.*
  • 백업하십시오! 이진 파일을 손상시킬 수 있으므로 위의 명령을 실행하기 전에.
  • 재귀에 globstar( **) 를 사용하려면로 활성화하십시오 shopt -s globstar.
  • 특정 파일 유형을 지정하려면 다음을 사용하십시오 **/*.c..

tabstop을 수정하려면을 추가하십시오 +'set ts=2'.

그러나 단점은 문자열 내부의 탭바꿀 수 있다는 것 입니다.

따라서 대체를 사용하여 약간 더 나은 해결책을 얻으려면 다음을 시도하십시오.

$ ex -s +'bufdo %s/^\t\+/  /ge' -cxa **/*.*

또는 exeditor + expandutility 를 사용하여 :

$ ex -s +'bufdo!%!expand -t2' -cxa **/*.*

후행 공백은 여러 파일에서 후행 공백을 제거하는 방법을 참조하십시오.


다음 기능을 추가 할 수 있습니다 .bash_profile.

# Convert tabs to spaces.
# Usage: retab *.*
# See: https://stackoverflow.com/q/11094383/55075
retab() {
  ex +'set ts=2' +'bufdo retab' -cxa $*
}

난 단지 당신 ;-) 이유는,이 스레드에 많은 답변을을 downvoted : :retab전혀없는 작업을 할 수 있습니다 , 쉘 글 로빙는 이런 종류의 물건에 대한 나쁜 솔루션입니다 , 당신의 :s명령을 대체 할 어떤 (2 공백 탭의 양을하는 당신 거의 절대 원치 않음), :!expand프로세스 를 실행하기 위해 예를 시작하는 것은 어리석은 일입니다 ...
Martin Tournoij

... 그리고 모든 솔루션은 바이너리 파일과 .png 파일, .pdf 파일 등을
클로버합니다

이것은 문서화에 대한 끔찍한 제안입니다. 하나는 이것을 이해하기 위해 여러 프로그램의 상당히 불투명 한 구문과 의미 론적 문제에 대해 잘 알고 있어야합니다.
Josip Rodin 10
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.