zzari
zzari

Reputation: 323

TCL Calculating the length of numbers and formatting properly in text file

I need to work on a text file with 3 columns of value like this:

  10 650  8456
  1  3264 64643
  ...

Now i have the following problems:

For each columns there are 8 space useful to write on numbers; if a numbers, for example, has 4 value like 8456, i want to count other 4 spaces (8 - 4) remaing and then at the 9th space write on second column, another number and so on.. Here an example of the desire output:

 |--01--||--02--||--03--|
 10      650     8456
 1       3264    64643

This is a piece of my code but i don't know how to count numbers and writing after the first numbers the others.

set FileOutput [open $Output w]
set FileInput     [open $filename r]

 set filecontent [read $FileInput]
 set inputList [split $filecontent "\n"]

 puts $FileOutputGas "        [lindex $inputList 3]        [lindex $inputList 4]        [lindex $inputList 5]"

but in this way i maintain always the same text format with fixed spaces between numbers; on the contrary i would like to put spaces dynamically.

EDIT: wrong output in this way:

 set formatStr {%-8d}
 puts   $FileOutputGas   "[format $formatStr [lindex $num 3]]"

It prints out the format "-8d" and not the number

EDIT 2: Problem with output when bind a button. The problem i was mentioned before was due to the push of a button. I don't know why the output is correct if i run your script, but if i insert all that action in a button it gives me a wrong output in this way:

 button .bCreate  -text "CREATE OUTPUT"  -width 30 -height 5 -activebackground green -font " -12" 
      bind .bCreateGas <1> {

 set Output "output.txt"
 set filename "input.txt"
 set FileOutput [open $Output w]
 set FileInput     [open $filename r]

 set filecontent [read $FileInput]
 set inputList [split $filecontent "\n"]

 set CtriaFind [lsearch -all -inline $inputList CTRIA3*]

 foreach line $CtriaFind { 
 # Extracting all the numbers in a line
 set numbers [ regexp -inline -all {\d+} $line ] 
 set num3 [lindex $numbers 3]
 set num4 [lindex $numbers 4]
 # Printing each numbers into the file
    puts -nonewline  $FileOutput  "        [ format "%-8d" $num3] [ format "%-8d" $num4]"
  puts  $FileOutput  ""; 
 } 
 }

a part of input.txt file is this one:

  GRID       48588        -.366712-3.443-2.3697197                        
  GRID       48606        -.366683-.0373640.374481                        
  GRID       48607        -.366536-3.888-2.3767999                        
  GRID       48608        -.366735-3.589-2.3721335                        
  $$
  $$  SPOINT Data
  $$
  CTRIA3    101268       0    9793    4098    9938                
  CTRIA3    101353       0    3986    9928    3803                
  CTRIA3    101363       0    4010   12337    3932   

i want to print only

 9793    4098
 3986    9928
 4010    12337

Upvotes: 0

Views: 1316

Answers (1)

Dinesh
Dinesh

Reputation: 16446

You need to make use of format command to format the display and regexp to retrieve the numbers in each line.

set Output "output.txt"
set filename "input.txt"
set FileOutput [open $Output w]
set FileInput     [open $filename r]

 set filecontent [read $FileInput]
 set inputList [split $filecontent "\n"]

 #puts $inputList

 foreach line $inputList { 

    # Extracting all the numbers in a line
    set numbers [ regexp -inline -all {\d+} $line ] 
    # Printing each numbers into the file
    foreach num $numbers {
        puts -nonewline  $FileOutput  "[ format "%-8d" $num ]"
    }
    puts  $FileOutput  ""; # This is just for the newline character
} 
close $filename 
close $FileOutput

The - used in the format command specifies that the converted argument should be left-justified in its field. The numbers 8 specifies the width of each field.

Reference : format

Update 1 :

There can be many ways. We have the whole list of numbers in a particular line in the list numbers. Afterwards we are iterating through the list with foreach. Here, instead of looping for all the elements, you can take only the 2nd element using [lindex $numbers 1].

Or, since we know that the elements are separated with spaces, instead of using these ways, we can directly assign it to one list and extract the second element from it. It all depends on your requirement only.

Upvotes: 2

Related Questions