用空格替换制表符以保持n空格对齐

时间:2015-09-08 13:00:32

标签: shell tabs whitespace

我正在尝试自动比较包含组织成列的数据的两组文件。有三个主要问题似乎使这个棘手:

  1. 集合A和集合B
  2. 之间的列顺序不同
  3. 设置A使用标签,设置B使用空格
  4. 在集合A中,某些列包含空格,集合B,它们包含默认值。
  5. 我试图做一些简单的shell脚本来将Set A重新排列成正确排序的列,例如awk '{print substr($0, 10, 10) substr($0, 20, 10)}等,但在这组文件中使用制表符意味着列以不一致的字符编号开头。

    我认为最简单的解决方案是用空格替换制表符,然后使用awk重新排列数据,如上所述。我应该如何更换一个标签,其中的空格数等于到达下一个制表位所需的数量(出于此目的,假设为8)。

    使用一定数量的空格替换选项卡显然不起作用,我在下面进行了测试。

    $ echo "A\tB\nA \tB\nA  \tB\nA   \tB\n" > test
    $ cat test
    A       B
    A       B
    A       B
    A       B
    $ cat test | sed 's/\t/    /g'
    A    B
    A     B
    A      B
    A       B
    

    显然,这可以通过编写一些代码来解决,这些代码确定了制表符处的位置,然后填充适当数量的空格字符以实现对齐,但似乎应该有一个更简单的解决方案,我可能不见了。 (或者打开vim中的每个文件并使用:retab,但必须有更好的选择!)

    注意:由于某些数据集中存在空白,我无法column重新排列数据。

2 个答案:

答案 0 :(得分:2)

由于您在标签前有空格,因此您可以使用此sed:

sed $'s/ *\t/    /g' test
A    B
A    B
A    B
A    B 

这也将在标签前用4个空格替换0或更多空格。

答案 1 :(得分:0)

给出以下awk脚本:

BEGIN {
  tabSize = 8;
}
{
  str = $0;
  idx = index(str, "\t");
  while (idx > 0) {
    left = substr(str, 0, idx);
    right = substr(str, idx + 1);
    spaces = sprintf("% " ((tabSize + 1) - (idx % tabSize)) "s", "");
    str = left spaces right;
    idx = index(str, "\t");
  }
  print str;
}

您可以执行此命令:

cat test | awk -f tab2spaces.awk

此脚本适用于任何内容。