awk:我想使用输入文件名生成一个同名不同扩展名的输出文件

时间:2018-03-20 08:22:00

标签: awk filenames

我有一个看起来像这样的脚本:

#! /bin/awk -f

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

像这样调用脚本:./myscript.awk test.txt

非常简单 - 获取一个文件并添加" start"到了开始和#34;结束"到最后。

现在我想获取输入文件名,让我们调用它test.txt,然后将输出打印到名为test.out的文件中。

所以我尝试打印输入文件名:

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

但那印刷了:fname: '' :(

其余的我可以弄清楚我认为,我有以下打印到硬编码的文件名:

#! /bin/awk -f

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

这很有效。

所以问题是:

  1. 如何获取输入文件名?
  2. 假设我以某种方式获取变量中的输入文件名,例如FILENAME包含" test.txt"我将如何制作另一个变量,例如OUTFILE,包含" test.out"?
  3. 注意:我会做更多的awk处理,所以请不要建议使用sed或其他语言:))

3 个答案:

答案 0 :(得分:1)

$ 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

FILENAME保存到变量,使用sub更改扩展名,然后根据需要进行打印

来自gawk manual

  

在BEGIN规则中,FILENAME的值为“”,因为尚未处理输入文件

答案 1 :(得分:1)

尝试这样的事情:

#! /bin/awk -f

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

我在close()语句中也建议END{}该文件。好好打电话给Sundeep,指出在BEGIN中FILENAME是空的。

答案 2 :(得分:1)

如果您使用的是GNU awk(gawk),则可以使用模式BEGINFILEENDFILE

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

然后,您可以使用主outfile循环的变量{...}。 这样做将允许您在单个awk命令中处理更多的1个文件。