How do I iteratively replace lines in a file?
Kai Meyer
kai at unixlords.com
Sun Mar 20 12:39:13 PDT 2011
On 03/20/2011 09:46 AM, Andrej Mitrovic wrote:
> Yeah, I've already done exactly as you guys proposed. Note however
> that `inputfile` and `outputfile` should be declared inside the
> foreach loop. Either that or you have to call `close()` explicitly. If
> you don't do that, file handles don't get released, and you'll
> eventually get back a stdio error such as "too many file handles
> opened". You could loose files this way. I know this because it just
> happened yesterday while testing. :p
>
> Anywho, I needed a quick script to append a semicolon to import lines
> because I managed to screw up some files when using sed to replace
> some lines. It's a quick hack but worked for me:
>
> import std.stdio;
> import std.file;
> import std.stdio;
> import std.path;
> import std.string;
>
> void main()
> {
> File inputfile;
> File outputfile;
> string newname;
>
> foreach (string name; dirEntries(r".", SpanMode.breadth))
> {
> if (!(isFile(name)&& getExt(name) == "d"))
> {
> continue;
> }
>
> newname = name.idup ~ "backup";
> if (exists(newname))
> {
> remove(newname);
> }
>
> rename(name, newname);
>
> inputfile = File(newname, "r");
> outputfile = File(name, "w");
>
> foreach (line; inputfile.byLine)
> {
> if ((line.startsWith("private import") ||
> line.startsWith("import"))&&
> !line.endsWith(",")&&
> !line.endsWith(";"))
> {
> outputfile.writeln(line ~ ";");
> }
> else
> {
> outputfile.writeln(line);
> }
> }
>
> inputfile.close();
> outputfile.close();
> }
>
> foreach (string name; dirEntries(r".", SpanMode.breadth))
> {
> if (getExt(name) == "dbackup")
> {
> remove(name);
> }
> }
> }
Funny, I would have just fixed it with sed.
sed -ir 's/^(import.*)/\1;' *.d
Infact, I think sed is actually a great example of an application that
you apply a search and replace on a per-line basis. I'd be curious if
somebody knows how their '-i' flag (for in-place) works. Based on the
man page, I'll bet it opens the source read-only, and opens the
destination write-only like Andrej's example.
-i[SUFFIX], --in-place[=SUFFIX]
edit files in place (makes backup if extension supplied)
The SUFFIX option just renames the original instead of deleting at the end.
More information about the Digitalmars-d-learn
mailing list