Cómo imprimir valores en un archivo de texto en un archivo con columnas usando el script de shell


11

Tengo un output.txt de ejecutar un script de shell de la siguiente manera:

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

El archivo de texto tiene múltiples entradas línea por línea de la misma manera. Quiero imprimir estos valores en columnas: Nombre de archivo, Estado y Marca de tiempo de la siguiente manera:

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

44
El formato de ejemplo no es un archivo CSV, es un archivo de ancho de columna fijo. Es posible que desee aclarar la pregunta o proporcionar un ejemplo correcto.
AlexP

Su ejemplo no es un formato CVS. El formato CVS es abc.txt,errorstatus1,Fri Nov 11 02:00:09 2016. Edité su pregunta para que coincida con lo que dice con el ejemplo que proporcionó. Siéntase libre de retroceder, pero tenga en cuenta que realmente necesita aclarar qué es exactamente lo que quiere: valores en columnas o valores separados por comas
Sergiy Kolodyazhnyy

Respuestas:


14

Con paste:

paste - - - <file.txt

esto generará el contenido del archivo separado de nueva línea como columnas y tres columnas separadas por tabulaciones por línea.

Agregar el encabezado:

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

Para columnizar la salida, tome ayuda de column:

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

Ejemplo:

% 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

¡Frio! ¡¡Gracias!! Pero, ¿cómo imprimir estos valores en formato Excel? Quiero los encabezados de columna en la hoja de Excel como Estado del nombre de archivo y Marca de tiempo y los valores debajo de ellos
linux09

@ linux09 Cree un CSV e importe con Excel:echo Filename,Status,Timestamp; paste -d ',' - - - <file.txt
heemayl

¡Brillante! Funciona de maravilla. Muchas gracias
linux09

6

Podrías usar awk:

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

La salida podría no ser tan bonita:

$ 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

En su %s\tlugar, podría usar para resultados separados por tabulaciones.

  • NR % 3es cero (y falso) para cada tercera línea, por lo que las otras líneas se imprimen con un espacio después de ellas en lugar de una nueva línea. nextsolo comienza la siguiente iteración.
  • Cada tercera línea se imprime tal cual, debido a la final 1, con una nueva línea después, ya que no coincide con el primer bloque.

5

También hay rs( utilidad BSD r e s 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.

En particular,

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

Entonces

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

o (para agregar el encabezado)

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

Para completar, también puede hacer esto con sed:

sed -e '1iFilename\tStatus\tTimestamp' -e 'N;N;y/\n/\t/' file.txt
  • 1iFilename\tStatus\tTimestamp inserta la línea de encabezado antes de la línea 1
  • N;N lee dos líneas más en el buffer del patrón, dando un total de 3 líneas separadas por nueva línea
  • y/\n/\t/ reemplaza todas las líneas nuevas con pestañas en el búfer de patrones

Los comandos i, Ny ysed se documentan aquí .


Genial ... ¿Podrías también comentar brevemente las expresiones que usaste? ¡gracias!
Campa

sí, amigo perfecto
Campa

1

Siempre es posible cocinar algo para el procesamiento de texto con AWK o Perl, y por supuesto Python, que es lo que proporciona esta respuesta.

Como one-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

Como secuencia de comandos de varias líneas

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

La idea básica aquí es proporcionar la entrada del script a través de stdin (usando la redirección de shell <, aunque también se puede usar una tubería). El script usa pestañas para separar los campos, aunque los espacios también podrían usarse para una salida más "afinada".

Salida de muestra utilizando el ejemplo de entrada proporcionado por 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
Al usar nuestro sitio, usted reconoce que ha leído y comprende nuestra Política de Cookies y Política de Privacidad.
Licensed under cc by-sa 3.0 with attribution required.