如何将制表符转换为一个目录的每个文件中的空格(可能递归)?

此外,是否有一种方法来设置每个制表符的空格数?


当前回答

没有人提到rpl?使用rpl可以替换任何字符串。 要将制表符转换为空格,

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

非常简单。

其他回答

将制表符转换为空格只是在”。Lua " files [tab -> 2个空格]

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

你可以使用vim:

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

正如Carpetsmoker所说,它将根据你的vim设置重新标签。文件中的modeline(如果有的话)。此外,它不仅将替换行首的制表符。这通常不是你想要的。例如,你可能有文字,包含制表符。

Git存储库友好方法

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保持文件权限不变:https://unix.stackexchange.com/questions/20645/clone-ownership-and-permissions-from-another-file不幸的是,我找不到一个简洁的POSIX替代方案。

如果你的代码库有一个疯狂的想法,允许在字符串中使用功能原始制表符,使用:

expand -i

然后一个接一个地浏览所有非行开头的制表符,你可以列出:是否可能为制表符git grep ?

在Ubuntu 18.04上测试。

从Gene的回答中收集最好的评论,到目前为止最好的解决方案是使用moreutils的海绵。

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在子shell中为每个文件名执行以下命令,{} expand -t 4将所有tab扩展为4个空格 海绵吸收标准输入(从扩展)并写入文件(同一文件)*。

注意:*一个简单的文件重定向(> "$0")在这里不能工作,因为它会很快覆盖文件。

优点:保留所有原始文件权限,不使用中间的tmp文件。

在其他答案中建议的使用expand似乎是仅用于此任务的最合乎逻辑的方法。

也就是说,它也可以用Bash和Awk来完成,以防你想在它的同时做一些其他的修改。

如果使用Bash 4.0或更高版本,shopt内置的globstar可以使用**进行递归搜索。

在GNU Awk 4.1或更高版本中,sed可以像“inplace”一样修改文件:

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