Take the 2-minute tour ×
Super User is a question and answer site for computer enthusiasts and power users. It's 100% free, no registration required.

On Linux I have the file orig-file.txt. This file include 4 fields now, but they could be less or more (this file is generated by other application).

What is the best option to translate the orig-file.txt to a file like output-file.txt file (it could be with a shell script or awk, etc.)

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

output-file.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

---

example from awk lang -( but its not work -:(

# 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
share|improve this question
    
Neither your original nor the output file are CSV here. –  slhck Apr 17 '12 at 14:36
    
OK see my update ( I delete the CSV word ) you right not CSV but other file with specific structure –  yael Apr 17 '12 at 14:38
    
Hm. I'm sorry for picking these words, but this is a stupid file structure to manipulate. If it were a CSV file it'd be super easy, but this here is almost impossible to parse. Can't you get the data in another format? –  slhck Apr 17 '12 at 14:39
    
who is stupied file - orig-file.txt ? or output-file.txt ? - what your seggestion ? please give me other example to what the best format that I can to get from orig-file.txt file ? –  yael Apr 17 '12 at 15:02
1  
output-file.txt is a bad format in my eyes. It is a lot less clear to even read manually than orig-file.txt imho. –  Daniel Andersson Apr 17 '12 at 15:14
show 1 more comment

2 Answers

up vote 0 down vote accepted

Here's some plain 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

Update for flexible number of fields:

I substitute the space in the datetime field to make things easier to parse

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
}
share|improve this answer
    
ok very cool - but what I will do if my file will contain 5 or 6 fields and not 4 - can we create more Flexible syntax ?? that support any numbers of fields ??? ( for example I have parameter that defined the number of fields - NUM_OF_FIELDS ) –  yael Apr 17 '12 at 15:51
    
example example [[ $NUM_OF_FIELDS -eq 4 ]] && read t1 t2 t3 t4 or [[ $NUM_OF_FIELDS -eq 5 ]] && read t1 t2 t3 t4 t5 ...etc –  yael Apr 17 '12 at 15:58
    
@yael, updated to use arrays. –  glenn jackman Apr 17 '12 at 16:22
add comment

This does the job in this case. Trivial modification needed if more fields are added.

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" needs both $1 and $2 since the date itself is whitespace separated.


It can be modified to read the field names from the header, but there is the problem with the date being whitespace separated. If other fields also are allowed to contain whitespace, manual modifications will always be needed to compensate such as in the $1" "$2 case.

share|improve this answer
    
but how to build this awk in to my ksh script ? , second what I need to add in case we have five fields or more ? –  yael Apr 17 '12 at 15:17
1  
@yael: just as you would do with any other tool. Pipe it, or let it read from a temp file, and so on. This is not in your current question scope. –  Daniel Andersson Apr 17 '12 at 15:19
    
ok but see my update awk not work on ksh shell ? –  yael Apr 17 '12 at 15:26
    
@yael: I use a backslash at the end of some lines to be able to continue writing on the line below for clarity in presentation. Just remove all backslashes that end lines, and then remove all line breaks to write the entire command on a single line. This should work universally. –  Daniel Andersson Apr 17 '12 at 15:29
add comment

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.