Cara mencetak nilai dalam file teks ke file kolom menggunakan skrip shell


11

Saya memiliki output.txt dari menjalankan skrip shell sebagai berikut:

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

File teks memiliki beberapa entri baris demi baris dengan cara yang sama. Saya ingin mencetak nilai-nilai ini ke dalam kolom: Nama file, Status, dan Stempel Waktu sebagai berikut:

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

4
Format contoh bukan file CSV, ini adalah file dengan lebar kolom tetap. Anda mungkin ingin mengklarifikasi pertanyaan atau memberikan contoh yang benar.
AlexP

Contoh Anda bukan format CVS. Format CVS adalah abc.txt,errorstatus1,Fri Nov 11 02:00:09 2016. Saya mengedit pertanyaan Anda untuk mencocokkan apa yang dikatakannya dengan contoh yang Anda berikan. Jangan ragu untuk mundur, tetapi harap dicatat bahwa Anda benar-benar perlu mengklarifikasi apa yang sebenarnya Anda inginkan - nilai kolom atau nilai yang dipisahkan koma
Sergiy Kolodyazhnyy

Jawaban:


14

Dengan paste:

paste - - - <file.txt

ini akan menampilkan konten file yang dipisahkan baris baru sebagai kolom, dan tiga kolom terpisah tab per baris.

Menambahkan tajuk:

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

Untuk membuat kolom output, ambil bantuan dari column:

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

Contoh:

% 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

Keren! Terima kasih!! Tetapi bagaimana cara mencetak nilai-nilai ini dalam format excel. Saya ingin tajuk Kolom di lembar excel sebagai Nama
File

@ linux09 Buat CSV dan impor dengan Excel:echo Filename,Status,Timestamp; paste -d ',' - - - <file.txt
heemayl

Cemerlang! Bekerja seperti pesona. Terima kasih banyak
linux09

6

Anda bisa menggunakan awk:

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

Output mungkin tidak secantik:

$ 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

Anda dapat menggunakan %s\tsebagai gantinya untuk output yang dipisahkan-tab.

  • NR % 3adalah nol (dan salah) untuk setiap baris ketiga, jadi baris lainnya dicetak dengan spasi setelah mereka alih-alih baris baru. nextbaru mulai iterasi berikutnya.
  • Setiap baris ketiga dicetak apa adanya karena final 1, dengan baris baru setelahnya, karena tidak cocok dengan blok pertama.

5

Ada juga rs(BSD r e s utilitas hape):

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.

Khususnya,

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

Begitu

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

atau (untuk menambahkan tajuk)

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

Untuk kelengkapan, Anda dapat melakukan ini sedjuga dengan :

sed -e '1iFilename\tStatus\tTimestamp' -e 'N;N;y/\n/\t/' file.txt
  • 1iFilename\tStatus\tTimestamp menyisipkan baris header sebelum baris 1
  • N;N membaca dua baris lagi ke buffer pola, memberikan total 3 baris yang dipisahkan baris baru
  • y/\n/\t/ mengganti semua baris baru dengan tab di buffer pola

Perintah i, Ndan ysed didokumentasikan di sini .


Hebat .. Bisakah Anda juga mengomentari secara singkat ekspresi yang Anda gunakan? Terima kasih!
Campa

ya, sobat sempurna
Campa

1

Selalu memungkinkan untuk memasak sesuatu untuk pemrosesan teks dengan AWK atau Perl, dan tentu saja Python, yang disediakan oleh jawaban ini.

Sebagai satu-liner:

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

Sebagai skrip multi-baris

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

Ide dasar di sini adalah untuk memberikan input skrip melalui stdin (menggunakan pengalihan shell <, meskipun pipa dapat digunakan juga). Skrip menggunakan tab untuk memisahkan bidang, meskipun spasi dapat digunakan juga untuk keluaran yang lebih "disetel".

Output sampel menggunakan contoh input yang disediakan oleh 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
Dengan menggunakan situs kami, Anda mengakui telah membaca dan memahami Kebijakan Cookie dan Kebijakan Privasi kami.
Licensed under cc by-sa 3.0 with attribution required.