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


11

我从运行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,如下所示:

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

4
示例格式不是CSV文件,而是固定列宽文件。您可能需要澄清问题或提供正确的示例。
AlexP

您的示例不是 CVS格式。CVS格式为abc.txt,errorstatus1,Fri Nov 11 02:00:09 2016。我编辑了您的问题,使其与您提供的示例相符。随时回滚,但请注意,您确实需要弄清楚您想要的是什么-列值或逗号分隔的值
Sergiy Kolodyazhnyy

Answers:


14

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

凉!谢谢!!但是如何以excel格式打印这些值。我想要Excel工作表中的列标题作为文件名状态和时间戳以及它们下面的值
linux09

@ linux09创建CSV并使用Excel导入:echo Filename,Status,Timestamp; paste -d ',' - - - <file.txt
heemayl 2016年

辉煌!奇迹般有效。非常感谢
linux09 '16

6

您可以使用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只是开始下一次迭代。
  • 由于final 1,每三行都按原样打印,因为它与第一个块不匹配,所以在其后加上换行符。

5

还有rs(BSD [R Ë 小号高原肺水肿实用程序):

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

3

为了完整起见,您也可以这样做sed

sed -e '1iFilename\tStatus\tTimestamp' -e 'N;N;y/\n/\t/' file.txt
  • 1iFilename\tStatus\tTimestamp 在第1行之前插入标题行
  • N;N 将另外两行读入模式缓冲区,总共提供3条换行符
  • y/\n/\t/ 用模式缓冲区中的制表符替换所有换行符

iNysed的命令被记录在这里


很好。您还可以简要评论一下您使用的表达方式吗?谢谢!
坎帕

是的,完美伙计
坎帕

1

总是有可能为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
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.