How can I convert tabs to spaces in every file of a directory?

后端 未结 19 1314
既然无缘
既然无缘 2020-12-02 03:48

How can I convert tabs to spaces in every file of a directory (possibly recursively)?

Also, is there a way of setting the number of spaces per tab?

19条回答
  •  感动是毒
    2020-12-02 04:14

    Git repository friendly method

    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"
    )
    

    Act on all files under the current directory:

    git-tab-to-space
    

    Act only on C or C++ files:

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

    You likely want this notably because of those annoying Makefiles which require tabs.

    The command git grep --cached -Il '':

    • lists only the tracked files, so nothing inside .git
    • excludes directories, binary files (would be corrupted), and symlinks (would be converted to regular files)

    as explained at: How to list all text (non-binary) files in a git repository?

    chmod --reference keeps the file permissions unchanged: https://unix.stackexchange.com/questions/20645/clone-ownership-and-permissions-from-another-file Unfortunately I can't find a succinct POSIX alternative.

    If your codebase had the crazy idea to allow functional raw tabs in strings, use:

    expand -i
    

    and then have fun going over all non start of line tabs one by one, which you can list with: Is it possible to git grep for tabs?

    Tested on Ubuntu 18.04.

提交回复
热议问题