Cách in giá trị trong tệp văn bản thành tệp được phân loại bằng tập lệnh shell


11

Tôi có một output.txt từ việc chạy một kịch bản shell như sau:

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

Tệp văn bản có nhiều mục nhập theo từng dòng theo cùng một cách. Tôi muốn in các giá trị này thành các cột: Tên tệp, Trạng thái và Dấu thời gian như sau:

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

4
Định dạng ví dụ không phải là tệp CSV, nó là tệp có chiều rộng cột cố định. Bạn có thể muốn làm rõ câu hỏi hoặc cung cấp một ví dụ chính xác.
AlexP

Ví dụ của bạn không phải là định dạng CVS. Định dạng CVS là abc.txt,errorstatus1,Fri Nov 11 02:00:09 2016. Tôi đã chỉnh sửa câu hỏi của bạn để phù hợp với những gì nó nói với ví dụ bạn cung cấp. Vui lòng quay lại, nhưng xin lưu ý rằng bạn thực sự cần phải làm rõ chính xác những gì bạn muốn - giá trị cột hoặc giá trị được phân tách bằng dấu phẩy
Sergiy Kolodyazhnyy

Câu trả lời:


14

Với paste:

paste - - - <file.txt

điều này sẽ xuất nội dung tệp được phân tách dòng mới dưới dạng cột và ba cột được phân tách bằng tab trên mỗi dòng.

Thêm tiêu đề:

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

Để phân loại đầu ra, hãy nhận trợ giúp từ column:

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

Thí dụ:

% 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

Mát mẻ! Cảm ơn!! Nhưng làm thế nào để in các giá trị này ở định dạng excel. Tôi muốn các tiêu đề Cột trong bảng excel là Trạng thái tên tệp và Dấu thời gian và các giá trị bên dưới chúng
linux09

@ linux09 Tạo CSV và nhập bằng Excel:echo Filename,Status,Timestamp; paste -d ',' - - - <file.txt
heemayl

Xuất sắc! Hoạt động như một lá bùa. Cảm ơn bạn rất nhiều
linux09

6

Bạn có thể sử dụng awk:

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

Đầu ra có thể không đẹp bằng:

$ 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

Bạn có thể sử dụng %s\tthay thế cho đầu ra được phân tách bằng tab.

  • NR % 3bằng 0 (và sai) cho mỗi dòng thứ ba, vì vậy các dòng khác được in bằng khoảng trắng sau chúng thay vì dòng mới. nextchỉ bắt đầu lần lặp tiếp theo
  • Mỗi dòng thứ ba được in như là vì cuối cùng 1, với một dòng mới sau nó, vì nó không khớp với khối đầu tiên.

5

Ngoài ra còn có rs( tiện ích hape của BSD r e s ):

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.

Đặc biệt,

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

Vì thế

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

hoặc (để thêm tiêu đề)

$ { 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

Để hoàn thiện, bạn cũng có thể làm điều này với sed:

sed -e '1iFilename\tStatus\tTimestamp' -e 'N;N;y/\n/\t/' file.txt
  • 1iFilename\tStatus\tTimestamp chèn dòng tiêu đề trước dòng 1
  • N;N đọc thêm hai dòng vào bộ đệm mẫu, cho tổng cộng 3 dòng mới được phân tách
  • y/\n/\t/ thay thế tất cả các dòng mới bằng các tab trong bộ đệm mẫu

Các i, Nylệnh sed được ghi nhận ở đây .


Tuyệt vời .. Bạn cũng có thể nhận xét ngắn gọn về các biểu thức bạn đã sử dụng? cám ơn!
Campa

vâng, anh chàng hoàn hảo
Campa

1

Luôn luôn có thể nấu một cái gì đó để xử lý văn bản bằng AWK hoặc Perl, và tất nhiên Python, đó là những gì câu trả lời này cung cấp.

Như một lớp lót:

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

Như tập lệnh nhiều dòng

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) ])

Ý tưởng cơ bản ở đây là cung cấp đầu vào tập lệnh thông qua stdin (sử dụng chuyển hướng của shell <, mặc dù cũng có thể sử dụng một đường ống). Kịch bản sử dụng các tab để phân tách các trường, mặc dù các khoảng trắng cũng có thể được sử dụng cho đầu ra "tinh chỉnh" hơn.

Đầu ra mẫu sử dụng ví dụ đầu vào do OP cung cấp:

$ 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
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.