clalias All American 1580 Posts user info edit post |
I need to open a bunch of *.f files and replace strings like
structure /foo/ ------>> TYPE :: foo
so basically it needs to search for the " structure / * /" string and copy "*" then replace it with "TYPE :: * ". and there are 6 blank spaces in front of the string and those need to stay.
I really need to do a lot more than this but I would really appreciate if someone could help me get started.
[Edited on March 1, 2007 at 12:20 PM. Reason : .] 3/1/2007 12:16:29 PM |
dFshadow All American 9507 Posts user info edit post |
how many is a bunch? 3/1/2007 12:20:27 PM |
qntmfred retired 40726 Posts user info edit post |
do you know perl or any other language?
[Edited on March 1, 2007 at 12:25 PM. Reason : or do you use a text editor that can do search/replace with regex] 3/1/2007 12:24:32 PM |
clalias All American 1580 Posts user info edit post |
^^hundreds
^yes. jedit, textpad on win32. and no on the perl, but I need to.
I would perfer a sed command or script. but I'll take whatever. Basically whatever would be the quickest to get me started.
[Edited on March 1, 2007 at 12:30 PM. Reason : .] 3/1/2007 12:28:43 PM |
qntmfred retired 40726 Posts user info edit post |
this is how i would do it in my editor, editplus. see if your editor can do something like that. if you are going to be doing this often, it might be better to write a script. tell us what language(s) you know so we can tell you how to do it. i could tell you how to do it a few different ways, but if you're not comfortable with that language/environment, it'll take you even longer
if you can do it with sed, here is the shell script
for file in *.f do sed -f scriptname.txt $file > $file done
[Edited on March 1, 2007 at 12:38 PM. Reason : .] 3/1/2007 12:29:58 PM |
clalias All American 1580 Posts user info edit post |
^I tried that in jEdit and it returned "Type :: 1" ??
I don't know perl, though I wish i did. I am going to learn it, just never had a reason to.
actually I have many different expression I need to search for and replace for hundreds of files. That's why I would prefer a set of sed commands.
I have used sed. If given a script I could run it. If I can just figure out how to copy elements and replace them in different expressions I could figure out the rest of what I need to do. ------------
^yeah that's it. I just need the sed script. If you know the command to do this that would be very helpful.
[Edited on March 1, 2007 at 12:43 PM. Reason : .] 3/1/2007 12:41:44 PM |
clalias All American 1580 Posts user info edit post |
oh and the variable name could be underscored like "fuck_shit" in case that needs to be escaped or something.
I did this yesterday for stuff like
s/REAL\*\([48]\)/real (kind =\1) but I'm unclear about how to copy an entire string easily.
----------------------------------------------
I just tried
s/structure\/\([a-z_]*\)/\1
I think this is close, but it sure as hell isn't right. not sure how to interpret the whitespaces and re-write them.
I'll keep trying things out, but I really appreciate any and all help.
[Edited on March 1, 2007 at 1:10 PM. Reason : .] 3/1/2007 12:47:51 PM |
State409c Suspended 19558 Posts user info edit post |
Quote : | "^I tried that in jEdit and it returned "Type :: 1" ??" |
Instead of slash 1, try dollar 1, ie $1
The $1 is what the parentheses are capturing from the search string3/1/2007 1:39:28 PM |
clalias All American 1580 Posts user info edit post |
^yep that worked. thanks!
it would still be nice to put this in a sed script. 3/1/2007 1:47:31 PM |
State409c Suspended 19558 Posts user info edit post |
I write mostly in perl for this stuff, sed is nice, but perl is a little bit more powerful (ie, I usually make .bak's of the files before edit).
I have a simple template for opening file(s) and either finding and replacing text or just removing it or removing the lines entirely. 3/1/2007 1:52:09 PM |
pmcassel All American 1553 Posts user info edit post |
#!/usr/bin/perl
use strict;
my $dirToCheck = "./"; my @newFileData = (); my $fh;
opendir(my $dir, $dirToCheck) or die "Error opening directory: $dirToCheck: $!"; while (defined(my $file = readdir($dir))) { if ($file =~ /^[^\.]+\.f$/) { #filename has one or more character excluding the period before ".f" #open open($fh, "<", $file) or die "Error opening file: $!"; while (<$fh> { s/regex_to_search_for/replace_with_me/; push @newFileData, $_; } close($fh); open($fh, ">", $file) or die "Error opening file: $!"; print $fh @newFileData; close($fh); } } closedir($dir); 3/1/2007 1:53:45 PM |
clalias All American 1580 Posts user info edit post |
^^if you could hook me up with that easily I could probably get it to work. I was just going with sed so I can write a script and run for all files easily, but if you have a template for that then that gets rid of that problem.
^ok let me digest that for a sec. Thanks!
[Edited on March 1, 2007 at 1:55 PM. Reason : .] ------------
OK so I just need to fill in the
s/regex_to_search_for/replace_with_me/;
thanks for your help
[Edited on March 1, 2007 at 1:57 PM. Reason : .] 3/1/2007 1:55:04 PM |
pmcassel All American 1553 Posts user info edit post |
pretty version: http://www.pasteserver.net/319 3/1/2007 1:58:57 PM |
pmcassel All American 1553 Posts user info edit post |
yeah, but you should backup your directory first just in case... or change the script to write to a .new file or something 3/1/2007 2:01:23 PM |
clalias All American 1580 Posts user info edit post |
^oh yeah, first thing I did I'm dangerous with this shit. 3/1/2007 2:03:56 PM |
split All American 834 Posts user info edit post |
Quote : | "for file in *.f do sed -f scriptname.txt $file > $file done " |
redirecting this way will wipe your source files
this sed statement should work
sed 's/\(\ \{6\}\)structure \/\(.*\)\//\1TYPE::\2/' file
[Edited on March 1, 2007 at 2:10 PM. Reason : -]3/1/2007 2:07:40 PM |
clalias All American 1580 Posts user info edit post |
^Fuck yeah --that works
thanks 3/1/2007 2:17:05 PM |
clalias All American 1580 Posts user info edit post |
OK I got a new one. I need to add the word "IMPLICIT NONE" after the last occurrence of the word "USE". From what I've been told this is not easy to do in sed, so a perl script would be best. I bought a perl book and I am going to learn it, but I need to get this done before I have time to learn it.
I can use the loop template above to open all files and write out new ones, but I just need the expression to insert. Here's what the source files will look like.
I don't know how many times the word "USE" will appear and I can't be sure of the next word that follows. Note that all words(except comments) begin no sooner than the 6th column--if that matters.
Subroutine c this line is a comment -- USE foo1 USE foo2 . c this is another comment -- . USE foon
// ----- insert "IMPLICIT NONE" on this line ------//
Real:: x Integer::i . . END Subroutine
Thanks all! 3/4/2007 7:07:05 PM |
State409c Suspended 19558 Posts user info edit post |
Typically, any time I am doing file processing, I read the lines into arrays. If you do it in this way, you can probably set up a counter so that you know which line was the last one you found USE on. Loop back through your array and when you get to the line that had the last USE, then spit out your new line after that, the rest of the file, then save.
But my scripts are on my work system, and I don't have access to them tonight. If someone else doesn't solve this for you, I'll paste mine in for you. 3/4/2007 7:29:41 PM |
clalias All American 1580 Posts user info edit post |
yeah, that'll work. I was wondering if there was a command to insert lines in perl. I'm not really sure how perl works but I was thinking you could read through the file and each time you encounter "USE" (as the first word on a line after 6 blank spaces) you record the line number then after end-of-file you just insert the phrase you want on line#+1. But I don't know if you can grab the line number or set up a line counter. thanks for your help--definitely check back tomorrow if you can.
[Edited on March 4, 2007 at 8:05 PM. Reason : .] 3/4/2007 8:04:38 PM |
split All American 834 Posts user info edit post |
I would think that an easier way might be to avoid counters altogether and just process the file backwards (and reverse again before printing). I haven't been able to figure out a sed one-liner for it, but the Perl script below should hopefully help get you started.
#!/usr/bin/perl -w use strict;
my $go = 1;; my @output;
open(FP,"input_file"); my @lines = <FP>; close(FP);
while(my $line = pop @lines) { if($line =~ /^\s{0,6}USE/ && $go) { $go = 0; push(@output,"IMPLICIT NONE\n"); } push(@output, $line); }
print reverse @output;
3/5/2007 5:49:59 PM |
clalias All American 1580 Posts user info edit post |
awesome!
Makes sense. I'll try it out tomorrow. Thanks a lot. 3/5/2007 7:13:13 PM |
State409c Suspended 19558 Posts user info edit post |
^^ Much sharper at perl than I.
I guess I had forgotten this works just fine for populating an array with your lines
open(FP,"input_file"); my @lines = <FP>; close(FP);
3/5/2007 9:56:17 PM |