code_fodder
code_fodder

Reputation: 16381

Awk: I want to use the input filename to generate an output file with same name different extension

I have a script that looks like this:

#! /bin/awk -f

BEGIN { print "start" }
{ print $0 }
END { print "end" }

Call the script like this: ./myscript.awk test.txt

Pretty simple - takes a file and adds "start" to the start and "end" to the end.

Now I want to take the input filename, lets call it test.txt, and print the output to a file called test.out.

So I tried to print the input filename:

BEGIN { print "fname: '" FILENAME "'" }

But that printed: fname: '' :(

The rest I can figure out I think, I have this following to print to a hard-coded filename:

#! /bin/awk -f

BEGIN { print "start" > "test.out" }
{ print $0 >> "test.out" }
END { print "end" >> "test.out" }

And that works great.

So the questions are:

  1. how do I get the input filename?
  2. Assuming somehow I get the input file name in a variable, e.g. FILENAME which contains "test.txt" how would I make another variable, e.g. OUTFILE, which contains "test.out"?

Note: I will be doing much more awk processing so please don't suggest to use sed or other languages :))

Upvotes: 1

Views: 2148

Answers (3)

oliv
oliv

Reputation: 13259

If you're using GNU awk (gawk), you can use the patterns BEGINFILE and ENDFILE

awk 'BEGINFILE{
        outfile=FILENAME; 
        sub(".txt",".out",outfile); 
        print "start" > outfile 
     }
     ENDFILE{
        print "stop" >outfile
     }' file1.txt file2.txt

You can then use the variable outfile your the main {...} loop. Doing so will allow you to process more that 1 file in a single awk command.

Upvotes: 1

Daemon Painter
Daemon Painter

Reputation: 3500

Try something like this:

#! /bin/awk -f

BEGIN { 
    file = gensub(".txt",".out","g",ARGV[1])
    print "start" > file
}
{ print $0 >> file }
END {
    print "end" >> file
    close(file)
}

I'd suggest to close() the file too in the END{} statement. Good call to Sundeep for pointing out that FILENAME is empty in BEGIN.

Upvotes: 1

Sundeep
Sundeep

Reputation: 23677

$ echo 'foo' > ip.txt
$ awk 'NR==1{op=FILENAME; sub(/\.[^.]+$/, ".log", op); print "start" > op}
       {print > op}
       END{print "end" > op}' ip.txt
$ cat ip.log 
start
foo
end

Save FILENAME to a variable, change the extension using sub and then print as required

From gawk manual

Inside a BEGIN rule, the value of FILENAME is "", because there are no input files being processed yet

Upvotes: 1

Related Questions