如何将制表符转换为一个目录的每个文件中的空格(可能递归)?
此外,是否有一种方法来设置每个制表符的空格数?
如何将制表符转换为一个目录的每个文件中的空格(可能递归)?
此外,是否有一种方法来设置每个制表符的空格数?
当前回答
尝试命令行工具expand。
expand -i -t 4 input | sponge output
在哪里
-i用于只展开每行的前导制表符; -t 4表示每个制表符将转换为4个空格字符(默认为8个)。 Sponge来自moreutils包,避免清除输入文件。在macOS上,moreutils包可以通过Homebrew (brew install moreutils)或MacPorts (sudo port install moreutils)获得。
最后,在使用Homebrew (brew install coreutils)或MacPorts (sudo port install coreutils)安装coreutils之后,可以在macOS上使用gexpand。
其他回答
对于递归应用程序,我喜欢上面的“find”示例。为了使其具有非递归性,只更改当前目录中匹配通配符的文件,shell glob扩展可以满足少量文件的需求:
ls *.java | awk '{print "expand -t 4 ", $0, " > /tmp/e; mv /tmp/e ", $0}' | sh -v
如果在您相信它工作之后希望它保持沉默,只需在sh命令的末尾加上-v。
当然,您可以在第一个命令中选择任何一组文件。例如,以受控的方式只列出一个特定的子目录(或多个目录),如下所示:
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
简单地用sed替换是可以的,但不是最好的解决方案。如果制表符之间有“额外的”空格,替换后它们仍然在那里,因此页边距将是粗糙的。在行中间展开的制表符也不能正常工作。在bash中,我们可以说相反
find . -name '*.java' ! -type d -exec bash -c 'expand -t 4 "$0" > /tmp/e && mv /tmp/e "$0"' {} \;
将展开应用到当前目录树中的每个Java文件。如果目标是其他文件类型,则删除/替换name参数。正如其中一条评论提到的,在删除name或使用弱通配符时要非常小心。你可以很容易地破坏存储库和其他隐藏的文件。这就是为什么最初的答案是这样的:
在尝试这样做之前,您应该始终对树进行备份,以防出现错误。
没有人提到rpl?使用rpl可以替换任何字符串。 要将制表符转换为空格,
rpl -R -e "\t" " " .
非常简单。
在其他答案中建议的使用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
尝试命令行工具expand。
expand -i -t 4 input | sponge output
在哪里
-i用于只展开每行的前导制表符; -t 4表示每个制表符将转换为4个空格字符(默认为8个)。 Sponge来自moreutils包,避免清除输入文件。在macOS上,moreutils包可以通过Homebrew (brew install moreutils)或MacPorts (sudo port install moreutils)获得。
最后,在使用Homebrew (brew install coreutils)或MacPorts (sudo port install coreutils)安装coreutils之后,可以在macOS上使用gexpand。