Создать новый файл с определенной структурой из текстового файла

Создать новый файл с определенной структурой из текстового файла

На Linux у меня есть файл orig-file.txt. Этот файл сейчас включает 4 поля, но их может быть меньше или больше (этот файл генерируется другим приложением).

Какой вариант лучше всего использовать для перевода orig-file.txtв файл типа file output-file.txt(это может быть скрипт оболочки или awk и т. д.)

оригинальный файл.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

выходной файл.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

---

пример из awk lang -( но он не работает -:(

# 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

решение1

Вот немного простого 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

Обновлятьдля гибкого количества полей:

Я заменяю пробел в поле даты и времени, чтобы упростить анализ

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
}

решение2

В данном случае это срабатывает. Если добавить больше полей, потребуется небольшая модификация.

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" требует и того $1, и другого, $2поскольку сама дата разделена пробелами.


Его можно изменить, чтобы считывать имена полей из заголовка, но есть проблема с датой, разделенной пробелами. Если другим полям также разрешено содержать пробелы, то всегда будут нужны ручные изменения для компенсации, как в этом $1" "$2случае.

Связанный контент