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.