Generar un nuevo archivo con una estructura específica a partir de un archivo de texto

Generar un nuevo archivo con una estructura específica a partir de un archivo de texto

En Linux tengo el archivo orig-file.txt. Este archivo ahora incluye 4 campos, pero pueden ser más o menos (este archivo lo genera otra aplicación).

¿Cuál es la mejor opción para traducir a orig-file.txtun archivo similar a un output-file.txtarchivo (podría ser con un script de shell o awk, etc.)

archivo-original.txt

CREATE_TIMESTAMP              TELEPHONE_NUMBER             ID TYPE
-------------------           -------------------- ---------- -----------------
24-09-2009 16:17:45           33633333333                  20 other_mmm_phone
24-09-2009 17:45:07           33644444444                  20 other_mmm_phone
07-10-2009 10:45:49           12312312312                  20 legacyphone
07-10-2009 11:46:38           59320000043                  20 other_mmm_phone

archivo-salida.txt

CREATE_TIMESTAMP -> 24-09-2009 16:17:45
TELEPHONE_NUMBER -> 33633333333
ID               -> 20
TYPE             -> other_mmm_phone



---



CREATE_TIMESTAMP -> 24-09-2009 16:17:45
TELEPHONE_NUMBER -> 33633333333
ID               -> 20
TYPE             -> other_mmm_phone

---

ejemplo de awk lang -( pero no funciona -:(

# awk 'NR>2 {
 > printf "\
 > %-16s -> %s\n\
 > %-16s -> %s\n\
 > %-16s -> %s\n\
 > %-16s -> %s\
 > \n\n\n---\n\n\n",\
 >         "CREATE_TIMESTAMP", $1" "$2,\
 >         "TELEPHONE_NUMBER", $3,\
 >         "ID", $4,\
 >         "TYPE", $5}\
 > '   orig-file.txt
awk: newline in string near line 2
awk: syntax error near line 3
awk: illegal statement near line 3
awk: newline in string near line 7

Respuesta1

Aquí hay algunos ksh simples:

{
  read t1 t2 t3 t4
  maxlen=$(printf "%s\n" ${#t1} ${#t2} ${#t3} ${#t4} | sort -n | tail -1)
  fmt=$(printf "%%-%ds -> %%s" $maxlen)
  read line
  while read date time tel id type; do
    printf "$fmt\n" $t1 "$date $time" $t2 $tel $t3 $id $t4 $type
    print "\n\n\n---\n\n"
  done
} < orig-file.txt

Actualizarpara un número flexible de campos:

Sustituyo el espacio en el campo de fecha y hora para facilitar el análisis.

sed '3,$s/ /@@/' orig-file.txt | 
{
    read line
    set -A headings $line
    max=0
    for head in "${headings[@]}"; do (( max < ${#head} )) && max=${#head}; done
    fmt=$(printf "%%-%ds -> %%s" $max)

    read line

    while read line; do
        set -A fields $line
        i=0
        while (( i < ${#headings[@]} )); do
            printf "$fmt\n" ${headings[$i]} ${fields[$i]} | sed 's/@@/ /'
            (( i=i+1 ))
        done
        print "\n\n\n---\n\n"
    done
}

Respuesta2

Esto funciona en este caso. Se necesita una modificación trivial si se agregan más campos.

awk 'NR>2{
    printf "\
%-16s -> %s\n\
%-16s -> %s\n\
%-16s -> %s\n\
%-16s -> %s\
\n\n\n---\n\n\n",\
        "CREATE_TIMESTAMP", $1" "$2,\
        "TELEPHONE_NUMBER", $3,\
        "ID", $4,\
        "TYPE", $5}\
' orig-file.txt > output-file.txt

"CREATE_TIMESTAMP" necesita ambos $1y $2dado que la fecha en sí está separada por espacios en blanco.


Se puede modificar para leer los nombres de los campos del encabezado, pero existe el problema de que la fecha está separada por espacios en blanco. Si a otros campos también se les permite contener espacios en blanco, siempre serán necesarias modificaciones manuales para compensar, como en este $1" "$2caso.

información relacionada