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.txt
Was 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 $1
und $2
da 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" "$2
Fall immer manuelle Änderungen erforderlich, um dies auszugleichen.