【问题标题】:How to align different part of a text file which contain the distinct delimiters in Linux? [closed]如何对齐包含 Linux 中不同分隔符的文本文件的不同部分? [关闭]
【发布时间】:2019-11-09 14:28:58
【问题描述】:

我有一个文件如下,

b | b | c
aaaaaaaa | b |    c

1,2,3
10000,3,4,

我想将它与两个分隔符对齐,即|,。预期的输出文件是

b        | b | c
aaaaaaaa | b | c

1,     2, 3
10000, 3, 4,

可以用任何简单的命令来完成吗?命令不应干扰文件中的其他文本(不包含该分隔符)。

【问题讨论】:

  • 如果行包含两个分隔符怎么办?具有相同分隔符的行是否总是相邻?
  • 欢迎来到 Stack Overflow。 SO 是一个面向专业和爱好者程序员的问答网站。目标是您将一些自己的代码添加到您的问题中,以至少显示您为解决这个问题所做的研究工作。
  • "可以使用任何简单的命令来完成吗?" -- 我不这么认为,考虑到需要做什么--- 要么:阅读整个文件在中,并在此过程中找到每列的最大宽度;然后写出来,现在知道每个字段应该有多宽;或者:遍历文件以找到那些最大宽度,然后再遍历文件以读取一行并用正确的字段宽度写出,到一个新文件,您最终将移过原始文件(这种方法的优点:您永远不会读取 整个 文件,一次总是一行)。

标签: linux bash perl


【解决方案1】:

首先,您需要找到每列的宽度。一旦你有了它,你就可以轻松地创建一个sprintf 格式。

use List::Util qw( max );

my @a = (
    [qw( b b c )],
    [qw( aaaaaaaa b c )],
);

my @col_widths =
   map {
      my $col_idx = $_;
      max
         map { length($a[$_][$col_idx]) }
            0..$#a
   }
      0..$#{ $a[0] };

# 8, 1, 1 => "%-8s | %-1s | %s"
my $format =
   join " | ",
      map("%-${_}s", @col_widths[ 0..$#col_widths-1 ]),
      "%s";

say sprintf($format, @$_)
   for @a;

在第二种情况下,格式宽度中需要包含逗号的空格,并且除了最后一个之外的每个列值都需要添加一个逗号。

# 5, 1, 1 => "%-6s %-2s %s"
my $format =
   join " ",
      map({ sprintf("%%-%ss", $col_widths[$_]+1) }
         0..$#col_widths-1
      ),
      "%s";

say
   sprintf($format,
      map("$_,", @$_[ 0..$#$_-1 ]),
      $_->[-1],
   )
      for @a;

这些解决方案假定每行具有相同的列数。根据需要进行调整。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2020-03-25
    • 1970-01-01
    • 2018-06-29
    • 1970-01-01
    • 1970-01-01
    • 2019-09-24
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多