×
INTELLIGENT WORK FORUMS
FOR COMPUTER PROFESSIONALS

Contact US

Log In

Come Join Us!

Are you a
Computer / IT professional?
Join Tek-Tips Forums!
  • Talk With Other Members
  • Be Notified Of Responses
    To Your Posts
  • Keyword Search
  • One-Click Access To Your
    Favorite Forums
  • Automated Signatures
    On Your Posts
  • Best Of All, It's Free!

*Tek-Tips's functionality depends on members receiving e-mail. By joining you are opting in to receive e-mail.

Posting Guidelines

Promoting, selling, recruiting, coursework and thesis posting is forbidden.

Students Click Here

TCL to open and combine multiple text files extracting only integer values at specified lines

TCL to open and combine multiple text files extracting only integer values at specified lines

TCL to open and combine multiple text files extracting only integer values at specified lines

(OP)
Hi I am new to tcl programming. I am in process of creating a automation tcl and i would like to request for ur help.

Scenario:


I have multiple text files which contains integer data of some variables called nodes and ele.The sample file looks like this.

#C
##Id Files
Ele 15235,16845,555845,21452,451254
Nodes 15478,26558,78549,12547,12546,13556
Thickness 2.5
Nodal thickness 0

I have hundreds of those text files.

One similarity in all files is that in line 3 and 4 , we have the element ids and node ids

Now, the thing i would like to automate is that , i want to build a scripts in tcl, after running which, it reads all the node ids and elements ids in lines 3 and 4; only integer values (in all of those 100 txt files) and stores them in a separate txt file, each one for node and for element.

1. Final node txt file should have only node ids from all files

2. Final elem txt file should have only elem ids from all files

It is possible through array? how can we best code it in tcl. pls help. its urgent.
I lack direction. can u help me and guide me , how to create that tcl?

thank you in advance

RE: TCL to open and combine multiple text files extracting only integer values at specified lines

Hi RadicalGiant,

OK, you need a little help but first show us an effort what have you done so far.

You need to divide your complex task into simple tasks -i.e.:
1. create a procedure which reads one file line by line - for that you can use the tcl commands open, close and gets.
2. create a procedure which processes one line and if possible it extracts the desired numbers - for this you can use several string and list operations
3. create a procedure which delivers list of all files in a given directory and process this list - use the command glob.

Have you tried to solve something of these tasks ?


RE: TCL to open and combine multiple text files extracting only integer values at specified lines

Hi RadicalGiant,

As for the task no.2 (see my previous post): I would create 2 global lists (i.e. arrays): one for elements and other for nodes.
The procedure which processes lines should read this data from every file and append them to the global lists - e.g.:

CODE

proc process_line {line} {
  # input: line
  # output: modified global: lists elem_list, node_list
  global elem_list
  global node_list
  # try to match Elements
    ...
  if {$result} {
    # return a list of the numbers by the regex
    set temp_list [get_list_of_numbers $line]
    ...
    foreach ele $temp_list {
       ...
        # add the element to the global list
        lappend elem_list $ele
       ...
    }
  }
  ...
  # try to match Nodes
  ...
}

proc get_list_of_numbers {line} {
  ...
  return $ret_list
} 

RE: TCL to open and combine multiple text files extracting only integer values at specified lines

Hi RadicalGiant,

Other tasks (from my previous post) are not difficult:
1. This procedure opens a file with a name from the argument for reading, then
reads it line by line and for every line calls other procedure (see my previous post. And at end it closes the file.

CODE

proc process_file {filename} {
  # input: filename to process
  set input_file [open $filename "r"]

  while { [gets $input_file line] != -1 } {
    # process line
    process_line $line
  }
  close $input_file
} 

3. If your data files would be in same directory named e.g. *.txt, then you could create a list of them using the glob command - like this:

CODE

proc get_list_of_files {} {
  # return sorted list of files matching a given pattern
  set files_to_process [glob ./*.txt]
  return [lsort $files_to_process]
} 

Let me know if you have other questions ...

RE: TCL to open and combine multiple text files extracting only integer values at specified lines

I posted some answers and I see that the OP is not responding ...
However, in the meantime as I tried to help OP how to start with this task, I created fully functional script which works according to the initial specification. Maybe, it wouldn't be good idea simply to throw it away, because it could help other beginning Tcl programmers how to start.
So, I rather post it here:
First I created some data files: radicalgiant_01.txt, radicalgiant_02.txt, radicalgiant_03.txt
which contain the data like given above - e.g.:
radicalgiant_01.txt

CODE

#C
##Id Files
Ele 15235,16845,555845,21452,451254
Nodes 15478,26558,78549,12547,12546,13556
Thickness 2.5
Nodal thickness 0 
... etc

Then I created the program - some procedures are discussed above:
radicalgiant.tcl

CODE

#!/usr/bin/tclsh

# ***** functions *****
proc process_file {filename} {
  # input: filename to process
  set input_file [open $filename "r"]

  while { [gets $input_file line] != -1 } {
    # process line
    process_line $line
  }
  close $input_file
}

proc process_line {line} {
  # input: line
  # output: modified global: lists elem_list, node_list
  global elem_list
  global node_list
  # try to match Elements
  set result [regexp {^\s*[Ee]le\s*} $line match]
  if {$result} {
    # return a list of the numbers by the regex
    set temp_list [get_list_of_numbers $line]
    puts [format "  ==> This was matched: %s %s" $match $temp_list]
    foreach ele $temp_list {
      if {[lsearch -exact $elem_list $ele]==-1}  {
        # add the element to the global list if it isn't already present
        lappend elem_list $ele
      } else {
        puts [format "  Warning: element %d already exists in elem_list!" $ele]
      }
    }
  }
  # try to match Nodes
  set result [regexp {^\s*[Nn]odes*\s*} $line match]
  if {$result} {
    # return a list of the numbers by the regex
    set temp_list [get_list_of_numbers $line]
    puts [format "  ==> This was matched: %s %s" $match $temp_list]
    foreach node $temp_list {
      if {[lsearch -exact $node_list $node]==-1}  {
        # add the element to the global list if it isn't already present
        lappend node_list $node
      } else {
        puts [format "  Warning: node %d already exists in node_list!" $node]
      }
    }
  }
}

proc get_list_of_numbers {line} {
  # return a list of the numbers by the regex
  set ret_list [regexp -all -inline {\d+} $line]
  return $ret_list
}

proc get_list_of_files {} {
  # return sorted list of files matching a given pattern
  set files_to_process [glob ./radicalgiant_??.txt]
  return [lsort $files_to_process]
}

proc write_data_fo_file {filename data} {
  set output_file [open $filename "w"]
  puts $output_file $data
  close $output_file
} 


# ***** main *****
# initialize lists
set elem_list {}
set node_list {}

# get list of files to process 
set file_list [get_list_of_files]
#puts [format "files found : %s " $file_list]

# process all files
foreach fname $file_list {
  # process file
  puts [format "* processing file: %s" $fname] 
  process_file $fname
  puts "current global lists:"
  puts [format "Ele : %s" $elem_list]
  puts [format "Node: %s" $node_list]
  puts ""
}

puts "Resulting global lists:"
puts [format "Ele : %s" $elem_list]
puts [format "Node: %s" $node_list]
puts ""

# write global lists to files
set fname "radicalgiant_elem.txt"
puts [format "Writing result to file: %s" $fname] 
write_data_fo_file $fname $elem_list
set fname "radicalgiant_node.txt"
puts [format "Writing result to file: %s" $fname] 
write_data_fo_file $fname $node_list
puts "done." 

Then running the script above causes this output and produces 2 files:

CODE

mikrom@mikrom-Lenovo-S500 ~/Work/Tcl_Tk $ tclsh radicalgiant.tcl
* processing file: ./radicalgiant_01.txt
  ==> This was matched: Ele  15235 16845 555845 21452 451254
  ==> This was matched: Nodes  15478 26558 78549 12547 12546 13556
current global lists:
Ele : 15235 16845 555845 21452 451254
Node: 15478 26558 78549 12547 12546 13556

* processing file: ./radicalgiant_02.txt
  ==> This was matched: Ele  15235 16855 665845 22452 461254
  Warning: element 15235 already exists in elem_list!
  ==> This was matched: Nodes  15478 26558 79549 13548 13546 14556
  Warning: node 15478 already exists in node_list!
  Warning: node 26558 already exists in node_list!
current global lists:
Ele : 15235 16845 555845 21452 451254 16855 665845 22452 461254
Node: 15478 26558 78549 12547 12546 13556 79549 13548 13546 14556

* processing file: ./radicalgiant_03.txt
  ==> This was matched: Ele  65235 56845 455845 31452 251254 111111
  ==> This was matched: Nodes  11478 11558 11549 11547 11546 11556 66666
current global lists:
Ele : 15235 16845 555845 21452 451254 16855 665845 22452 461254 65235 56845 455845 31452 251254 111111
Node: 15478 26558 78549 12547 12546 13556 79549 13548 13546 14556 11478 11558 11549 11547 11546 11556 66666

Resulting global lists:
Ele : 15235 16845 555845 21452 451254 16855 665845 22452 461254 65235 56845 455845 31452 251254 111111
Node: 15478 26558 78549 12547 12546 13556 79549 13548 13546 14556 11478 11558 11549 11547 11546 11556 66666

Writing result to file: radicalgiant_elem.txt
Writing result to file: radicalgiant_node.txt
done. 

The result file radicalgiant_elem.txt contains the numerical data for elements

CODE

15235 16845 555845 21452 451254 16855 665845 22452 461254 65235 56845 455845 31452 251254 111111 
and the file radicalgiant_node.txt contains similar data but for nodes.

Red Flag This Post

Please let us know here why this post is inappropriate. Reasons such as off-topic, duplicates, flames, illegal, vulgar, or students posting their homework.

Red Flag Submitted

Thank you for helping keep Tek-Tips Forums free from inappropriate posts.
The Tek-Tips staff will check this out and take appropriate action.

Reply To This Thread

Posting in the Tek-Tips forums is a member-only feature.

Click Here to join Tek-Tips and talk with other members! Already a Member? Login

Close Box

Join Tek-Tips® Today!

Join your peers on the Internet's largest technical computer professional community.
It's easy to join and it's free.

Here's Why Members Love Tek-Tips Forums:

Register now while it's still free!

Already a member? Close this window and log in.

Join Us             Close