如何使用 shell 脚本将文本文件中的值打印到列文件中

如何使用 shell 脚本将文本文件中的值打印到列文件中

我运行了一个 shell 脚本并得到了一个 output.txt 文件,如下所示:

abc.txt
errorstatus1
Fri Nov 11 02:00:09 2016
def.txt
errorstatus2.txt
Sat Nov 12 03:00:09 2016

文本文件以相同的方式逐行包含多个条目。我想将这些值打印到列中:文件名、状态和时间戳,如下所示:

Filename      Status        Timestamp
abc.txt     errorstatus1   Fri Nov 11 02:00:09 2016
def.txt     errorstatus2   Sat Nov 12 03:00:09 2016

答案1

paste

paste - - - <file.txt

这将输出换行符分隔的文件内容作为列,每行三个制表符分隔的列。

添加标题:

echo Filename Status Timestamp; paste - - - <file.txt

要将输出列化,请寻求以下帮助column

{ echo Filename Status Timestamp; paste - - - <file.txt ;} | column -t

例子:

% cat file.txt
abc.txt
errorstatus1
Fri Nov 11 02:00:09 2016
def.txt
errorstatus2.txt
Sat Nov 12 03:00:09 2016

% { echo Filename Status Timestamp; paste - - - <file.txt ;} | column -t
Filename  Status            Timestamp
abc.txt   errorstatus1      Fri        Nov  11  02:00:09  2016
def.txt   errorstatus2.txt  Sat        Nov  12  03:00:09  2016

答案2

您可以使用 awk:

awk 'NR % 3 {printf "%s ", $0; next}1'

输出可能不那么漂亮:

$ awk 'NR % 3 {printf "%s ", $0; next} 1' input
abc.txt errorstatus1 Fri Nov 11 02:00:09 2016
def.txt errorstatus2.txt Sat Nov 12 03:00:09 2016

您可以改用 %s\t制表符分隔的输出。

  • NR % 3每三行都为零(且为假),因此其他行后面会打印一个空格而不是换行符。next只是开始下一次迭代。
  • 每三行都按原样打印,因为1最后一个 后面有一个换行符,因为它与第一个块不匹配。

答案3

还有rs(BSDrshape 实用功能):

DESCRIPTION
     rs reads the standard input, interpreting each line as a row of blank-
     separated entries in an array, transforms the array according to the
     options, and writes it on the standard output.  With no arguments it
     transforms stream input into a columnar format convenient for terminal
     viewing.

尤其,

     -e      Consider each line of input as an array entry.

所以

$ rs -e < file
abc.txt                   errorstatus1              Fri Nov 11 02:00:09 2016
def.txt                   errorstatus2.txt          Sat Nov 12 03:00:09 2016

或(添加标题)

$ { printf '%s\n' Filename Status Timestamp ; cat file ; } | rs -e
Filename                  Status                    Timestamp
abc.txt                   errorstatus1              Fri Nov 11 02:00:09 2016
def.txt                   errorstatus2.txt          Sat Nov 12 03:00:09 2016

答案4

总是可以使用 AWK 或 Perl 以及 Python 来编写一些用于文本处理的东西,这就是这个答案所提供的。

作为一行代码:

python -c 'import sys;print "Filename\tStatus\tTimestamp"; lines=[l.strip() for l in sys.stdin];print "".join([l+"\n" if i%3 == 0 else l+"\t" for i,l in enumerate(lines,1) ])' < input.txt

作为多行脚本

import sys
print "Filename\tStatus\tTimestamp"
lines=[l.strip() for l in sys.stdin]
print "".join([l+"\n" if i%3 == 0 else l+"\t" for i,l in enumerate(lines,1) ])

这里的基本思想是通过 stdin 为脚本提供输入(使用 shell 的重定向<,尽管也可以使用管道)。脚本使用制表符来分隔字段,尽管也可以使用空格来获得更“精细”的输出。

使用OP提供的输入示例的示例输出:

$ python -c 'import sys;print "Filename\tStatus\tTimestamp";                                   
> lines=[l.strip() for l in sys.stdin];
> print "".join([l+"\n" if i%3 == 0 else l+"\t" for i,l in enumerate(lines,1) ])' < input.txt
Filename    Status  Timestamp
abc.txt errorstatus1    Fri Nov 11 02:00:09 2016
def.txt errorstatus2    Sat Nov 12 03:00:09 2016

相关内容