将制表符转换为许多文件中的空格


11

我有很多文件,其中的选项卡到处都是乱七八糟的,我想将它们全部转换成空格。我知道该expand命令,但是不幸的是,我将不得不使用它键入每个文件。在Linux上,有没有更简单的方法可以做到这一点?

Answers:


12

请尝试以下操作:

find ./ -type f -exec sed -i 's/\t/ /g' {} \;

如果要四个空格,请尝试:

find ./ -type f -exec sed -i 's/\t/    /g' {} \;

这样会将每个标签替换为一个空格。由于提到的人使用expand,因此我假设他/她希望保留文本的对齐方式。
garyjohn

您需要's/\t/ /g'每行替换多个标签。
丹尼尔·安德森

1
如果有很多文件正在执行find ./ -type f -exec sed -i ’s/\t/ /g’ {} +(即“ +”而不是“ \;”),并且该find版本支持(并且我个人还没有遇到任何不支持该功能的版本,但这不是POSIX标准),则可以大大提高速度,所以我猜可能会在某些系统上发生。请参见-exec command {} +手册中的“ ”。与其sed为每个文件启动一个实例,不如为构造一个带有系统支持的文件名参数的参数列表(getconf ARG_MAX在我的系统上= 2097152),xargs从而启动更少的sed进程。
丹尼尔·安德森

6
请注意以下发现的所有Mac用户:OS X的版本sed不了解\t制表符转义序列。您可以将其替换为文字制表符,可以在外壳程序中输入[Ctrl]+V, [Tab]
杰里米·班克斯(Jeremy Banks)说,住宿的家

expand可能比sed这更好,如下所述:stackoverflow.com/a/11094620/131824
David Weinraub 2013年

6

有很多方法可以做到这一点。如果您不小心,或者如果您不熟悉Linux,那么还有很多方法可以使自己立足。假设您可以通过使用类似方法find或使用编辑器手动创建要转换的文件列表,只需将该列表传递到以下文件中即可。

while read file
do
   expand "$file" > /tmp/expandtmp
   mv /tmp/expandtmp "$file"
done

可以用脚打死自己的一种方法是打错字,这样就可以将空文件移动到指定的所有文件名,从而删除所有文件的内容。因此,请小心并在备份的一小组文件上测试您首先执行的操作。


3
mv以成功的条件为expandexpand ... && mv ...
暂停,直到另行通知。

不要忘记expand -t 4将制表符扩展到4个空格。同样,此方法可以创建尾随换行符。但是否则它会起作用。
mgold 2014年

3
find . -type f -iname "*.js" -print0 | xargs -0 -I foo tab2space foo foo

-I foo 为每个输入行创建一个模板变量foo,因此您可以多次引用该输入。

-print0-0告诉两个命令使用\ 0作为行分隔符而不是SPACE,因此此命令适用于带有空格的路径。


1
find -name \*.js -exec bash -c 'expand -t 4 "$0" | tee "$0"' {} \;

缺点:
大于管道缓冲区大小(64KB)的文件被截断

优点:
没有
超过管道缓冲区大小的临时文件被截断


0

这个更好:

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

3
为什么这样更好?使用它不是一个好主意,/tmp/e因为如果其他任何文件正在使用该文件,则会将其弄乱。就像两个用户想同时使用它一样。
凯文·潘科2014年

0

考虑到以下要求,我对此问题做了一些尝试:

  • 根据文件名过滤文件,仅处理.cpp或.json文件
  • 支持并行处理。如果文件很多,可以大大提高速度
  • 该解决方案应放在一条线上以方便使用

最后一个要求是最难实现的,因为“扩展”不允许修改文件。

我想出了以下解决方案:

find . -type f -regextype egrep -regex '.*\.(c|cpp|h|hpp)'  -print0 | xargs -0 -n 1 -P 10 -IFILE bash -c ' ( echo "Processing FILE..." && expand -t 4 "FILE" > /tmp/expand.$$ && mv /tmp/expand.$$ "FILE" ) || exit 255'

这里是一些解释:

  • “查找”查找要处理的文件。“ -regextype egrep”允许基于其名称和“ egrep”格式的正则表达式对其进行过滤
  • “ -type f”参数可确保我们仅匹配常规文件,而不匹配目录或其他特殊文件
  • “ -regexp”参数是正则表达式本身,在这种情况下,它匹配以.c,.cpp,.h或.hpp结尾的任何文件(整个名称必须匹配,因此“ file.c2”将不匹配) ,这就是我们想要的)
  • “ -print0”指示“ find”在其标准输出上打印文件路径,每个路径的末尾都带有字符0。连同“ xargs”的选项“ -0”一起,它允许将包含回车的名称从一个工具传递到另一个(即使这种情况很少见……)
  • xargs为每个路径启动一个新进程(“ -n 1”),但可能并行运行多达10个进程(“ -P 10”)
  • xargs使用别名“ FILE”将每个文件路径传递给命令,这是一个bash脚本
  • bash脚本调用“ expand”,并将结果保存在一个临时文件中,该文件名包含当前进程ID($$),以便在给定文件上并行运行的所有进程都使用不同的临时文件
  • 整个命令使用模式(command1 && command2 && command3),以便在任何子命令返回错误时该过程将停止
  • 如果先前的“ &&”链有任何错误,bash脚本将返回退出代码255,这将导致xargs立即停止
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.