编写awk创建子文件夹并生成文件时报错,求问题排查与解决
问题描述
我的输入文件test.txt每条记录包含人名和数字(制表符分隔):
John 1 Mary 2
我已存在test文件夹,希望用awk程序为每条记录创建以人名为名的子文件夹,并在每个子文件夹中生成person.txt文件,内容为对应记录。预期目录结构如下:
test John person.txt # 内容为John\t1 Mary person.txt # 内容为Mary\t2
我编写了test.awk程序,运行时出现错误:
awk: test.awk:7: fatal: cannot redirect to 'test/John/person.txt': No such file or directory
第7行代码为:
print $0 >destination; fflush()
我的awk程序代码如下:
BEGIN { FS = OFS = "\t" while (getline <"test.txt" > 0) { foldername="test/" $1 system("if [ ! -d foldername ]; then mkdir foldername; fi") destination = foldername "/person.txt" print $0 >destination; fflush() } }
请问我哪里出错了?
错误分析与修正
你的核心错误是system命令中没有正确引用awk的变量foldername:shell把命令里的foldername当成了字面字符串,而非你定义的test/John这类实际路径,导致子文件夹根本没被创建,后续写入文件时自然会提示目录不存在。
修正方案
正确传递awk变量到shell:
用awk的字符串拼接,把变量值插入到system命令中,同时用转义双引号包裹路径(兼容人名含空格的情况):system("if [ ! -d \"" foldername "\" ]; then mkdir \"" foldername "\"; fi")更简洁的写法(推荐):
使用mkdir -p参数,它会自动创建不存在的目录,无需提前判断:system("mkdir -p \"" foldername "\"")
修正后的完整代码
BEGIN { FS = OFS = "\t" while (getline <"test.txt" > 0) { foldername="test/" $1 system("mkdir -p \"" foldername "\"") destination = foldername "/person.txt" print $0 >destination; fflush() } }
额外优化
其实不需要在BEGIN块里用getline读取文件,awk原生支持直接处理输入文件,写法更符合常规用法:
BEGIN { FS = OFS = "\t" } { foldername = "test/" $1 system("mkdir -p \"" foldername "\"") print $0 > foldername "/person.txt" fflush() }
运行时执行awk -f test.awk test.txt即可。
内容的提问来源于stack exchange,提问作者Roger Costello
相关产品推荐
相关产品推荐

