更好的粘贴命令

更好的粘贴命令

我有以下两个文件(我用点填充了行,因此文件中的每一行都具有相同的宽度,并将 file1 全部大写以使其更清晰)。

contents of file1:

ETIAM......
SED........
MAECENAS...
DONEC......
SUSPENDISSE

contents of file2

Lorem....
Proin....
Nunc.....
Quisque..
Aenean...
Nam......
Vivamus..
Curabitur
Nullam...

请注意,file2 比 file1 长。

当我运行这个命令时:

paste file1 file2

我得到这个输出

ETIAM...... Lorem....
SED........ Proin....
MAECENAS... Nunc.....
DONEC...... Quisque..
SUSPENDISSE Aenean...
    Nam......
    Vivamus..
    Curabitur
    Nullam...

我该怎么做才能使输出如下?

ETIAM...... Lorem....
SED........ Proin....
MAECENAS... Nunc.....
DONEC...... Quisque..
SUSPENDISSE Aenean...
            Nam......
            Vivamus..
            Curabitur
            Nullam...

我试过

paste file1 file2 | column -t

但它是这样做的:

ETIAM......  Lorem....
SED........  Proin....
MAECENAS...  Nunc.....
DONEC......  Quisque..
SUSPENDISSE  Aenean...
Nam......
Vivamus..
Curabitur
Nullam...

不像原始输出那么丑陋,但无论如何都是错误的列。

答案1

假设您的文件中没有任何制表符,

paste file1 file2 | expand -t 13

适当选择arg-t来覆盖 file1 中所需的最大行宽。

OP添加了更灵活的解决方案:

我这样做是为了在没有神奇数字 13 的情况下它也能工作:

paste file1 file2 | expand -t $(( $(wc -L <file1) + 2 ))

它不容易输入,但可以在脚本中使用。

答案2

我认为 awk 可能做得很好,所以我在谷歌上搜索“awk Reading input from two files”并发现stackoverflow 上的一篇文章用作起点。

首先是精简版,然后在下面进行完整评论。这花了几分钟才解决。我很高兴看到聪明人的一些改进。

awk '{if(length($0)>max)max=length($0)}
FNR==NR{s1[FNR]=$0;next}{s2[FNR]=$0}
END { format = "%-" max "s\t%-" max "s\n";
  numlines=(NR-FNR)>FNR?NR-FNR:FNR;
  for (i=1; i<=numlines; i++) { printf format, s1[i]?s1[i]:"", s2[i]?s2[i]:"" }
}' file1 file2

这是上述内容的完整记录版本。

# 2013-11-05 [email protected]
# Invoke thus:
#   awk -f this_file file1 file2
# The result is what you asked for and the columns will be
# determined by input file order.
#----------------------------------------------------------
# No matter which file we're reading,
# keep track of max line length for use
# in the printf format.
#
{ if ( length($0) > max ) max=length($0) }

# FNR is record number in current file
# NR is record number over all
# while they are equal, we're reading the first file
#   and we load the strings into array "s1"
#   and then go to the "next" line in the file we're reading.
FNR==NR { s1[FNR]=$0; next }

# and when they aren't, we're reading the
#   second file and we put the strings into
#   array s2
{s2[FNR]=$0}

# At the end, after all lines from both files have
# been read,
END {
  # use the max line length to create a printf format
  # the right widths
  format = "%-" max "s\t%-" max "s\n"
  # and figure the number of array elements we need
  # to cycle through in a for loop.
  numlines=(NR-FNR)>FNR?NR-FNR:FNR;
  for (i=1; i<=numlines; i++) {
     printf format, s1[i]?s1[i]:"", s2[i]?s2[i]:""
  }
}

答案3

在 Debian 及其衍生产品上,column有一个-n 诺默盖允许列对空字段执行正确操作的选项。在内部,column使用该wcstok(wcs, delim, ptr)函数,该函数将宽字符串拆分为由delim参数中的宽字符分隔的标记。

wcstokdelim在识别标记之前,首先跳过 中的宽字符。该-n选项使用的算法不会跳过delim.

不幸的是,这不是很可移植:-n是 Debian 特定的,并且column不在 POSIX 中,它显然是 BSD 的东西。

答案4

取出用于填充的点:

文件1:

ETIAM
SED
MAECENAS
DONEC
SUSPENDISSE

文件2:

Lorem
Proin
Nunc
Quisque
Aenean
Nam
Vivamus
Curabitur
Nullam

尝试这个:

$ ( echo ".TS"; echo "l l."; paste file1 file2; echo ".TE" ) | tbl | nroff | more

你会得到:

ETIAM         Lorem
SED           Proin
MAECENAS      Nunc
DONEC         Quisque
SUSPENDISSE   Aenean
              Nam
              Vivamus
              Curabitur
              Nullam

相关内容