Erstellen Sie aus einer Textdatei eine neue Datei mit einer bestimmten Struktur.

Erstellen Sie aus einer Textdatei eine neue Datei mit einer bestimmten Struktur.

Unter Linux habe ich die Datei orig-file.txt. Diese Datei enthält jetzt 4 Felder, es könnten aber weniger oder mehr sein (diese Datei wird von einer anderen Anwendung generiert).

orig-file.txtWas ist die beste Möglichkeit, es in eine dateiähnliche Datei zu übersetzen output-file.txt(das könnte mit einem Shell-Skript oder awk usw. sein)?

orig-datei.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

Ausgabedatei.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

---

Beispiel aus awk lang -( aber es funktioniert nicht -:(

# 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

Antwort1

Hier ist etwas einfaches KSH:

{
  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

Aktualisierenfür flexible Feldanzahl:

Ich ersetze das Leerzeichen im Datums-/Uhrzeitfeld, um die Analyse zu vereinfachen

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
}

Antwort2

Dies funktioniert in diesem Fall. Wenn weitere Felder hinzugefügt werden, sind nur geringfügige Änderungen erforderlich.

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“ benötigt beides $1und $2da das Datum selbst durch Leerzeichen getrennt ist.


Es kann so geändert werden, dass die Feldnamen aus der Kopfzeile gelesen werden, aber es besteht das Problem, dass das Datum durch Leerzeichen getrennt ist. Wenn auch andere Felder Leerzeichen enthalten dürfen, sind wie in diesem $1" "$2Fall immer manuelle Änderungen erforderlich, um dies auszugleichen.

verwandte Informationen