I need to open a bunch of *.f files and replace strings like structure /foo/ ------>> TYPE :: fooso 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
how many is a bunch?
3/1/2007 12:20:27 PM
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
^^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
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 longerif you can do it with sed, here is the shell scriptfor file in *.fdo sed -f scriptname.txt $file > $filedone [Edited on March 1, 2007 at 12:38 PM. Reason : .]
3/1/2007 12:29:58 PM
^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
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_]*\)/\1I 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
3/1/2007 1:39:28 PM
^yep that worked. thanks!it would still be nice to put this in a sed script.
3/1/2007 1:47:31 PM
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
#!/usr/bin/perluse 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
^^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
pretty version:http://www.pasteserver.net/319
3/1/2007 1:58:57 PM
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
^oh yeah, first thing I did I'm dangerous with this shit.
3/1/2007 2:03:56 PM
sed 's/\(\ \{6\}\)structure \/\(.*\)\//\1TYPE::\2/' file
3/1/2007 2:07:40 PM
^Fuck yeah --that works thanks
3/1/2007 2:17:05 PM
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.Subroutinec this line is a comment --USE foo1USE foo2.c this is another comment --.USE foon// ----- insert "IMPLICIT NONE" on this line ------//Real:: xInteger::i..END SubroutineThanks all!
3/4/2007 7:07:05 PM
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
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
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 -wuse 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
awesome! Makes sense. I'll try it out tomorrow. Thanks a lot.
3/5/2007 7:13:13 PM
^^ 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