为什么 awk 打印重定向失败?
Why print of awk failed to redirect?
我需要将配置文件 1 合并到配置文件 2。如果文件 1 有文件 2 没有,则将其附加到文件 2 的末尾。我可以用系统替换打印以修复错误,但我不知道为什么打印不起作用。
使用print i"=" a[i] >> ARGV[2];
,未能将文本追加到文本末尾
1.txt,注意第三行是空行:
key=5678
abc=000
- txt:
key=1234
test.awk:
#!/usr/bin/env -S gawk -F= -f
{
key = gensub(/\s/, "", "g", );
if (NR==FNR) {
a[key]=;
} else {
b[key]=;
}
}
END{
for (i in a) {
if (b[i] == "") {
print "bi = empty, append to end of file:" i"="a[i];
print i"="a[i] >> ARGV[2];
# system("echo " i "=" a[i] ">>" ARGV[2]);
} else if (a[i] != b[i]) {
cmd = sprintf("sed -i -r 's@\s*(%s)\s*=.*@\1=%s@' %s", i, a[i], ARGV[2]);
system(cmd);
}
}
}
运行 ./test.awk 1.txt 2.txt
结果:
$ ./test.awk 1.txt 2.txt
bi = empty, append to end of file:=
bi = empty, append to end of file:abc=000
$ cat 2.txt
key=5678
=
为什么 abc=000 没有添加到 2.txt?如果改成system("echo" i "=" a [i] ">" argv [2]),又OK了,是不是print有bug?
在gnu awk手册中,“5.9关闭输入和输出重定向”,需要调用close函数,当多个命令操作同一个文件时,例如pipe或cmd,
太糟糕了,所以我放弃打印>>,只使用system()。
最后,我使用这个脚本:
#!/usr/bin/env -S gawk -F"=|is" -f
# File: sync_kernelconfig.awk
# Author: Edward.Tang
# Mail: edaplayer@163.com
# Function: 同步文件1的内核配置到文件2
function set_value(array, comment, k, v)
{
if (!/^\s*#/) {
array[k]=v;
} else {
comment[k]=;
}
}
{
key = gensub(/#|\s/, "", "g", );
if (key == "") next; # 跳过空行
if (NR==FNR) {
set_value(a1, c1, key, );
} else {
set_value(a2, c2, key, );
line[key] = [=14=]; # line data of file2
}
}
END {
for (i in a1) {
if (a2[i] == "") {
if (c2[i] == "") {
system("echo " i "=" a1[i] ">>" ARGV[2]);
} else {
cmd = sprintf("sed -i -r 's~%s~%s=%s~' %s", line[i], i, a1[i], ARGV[2]);
system(cmd);
}
} else if (a1[i] != a2[i]) {
cmd = sprintf("sed -i -r 's~%s~%s=%s~' %s", line[i], i, a1[i], ARGV[2]);
system(cmd);
}
}
for (i in c1) {
if (a2[i] != "") {
cmd = sprintf("sed -i -r 's~%s~# %s is%s~' %s", line[i], i, c1[i], ARGV[2]);
system(cmd);
}
}
}
gnu awk手册中的“5.9关闭输入输出重定向”,需要调用close函数,当多个命令操作同一个文件时,比如pipe或cmd,就很糟糕了
所以我需要使用:
print i"="a[i] >> ARGV[2];
close(ARGV[2]);
或:
system("echo " i "=" a1[i] ">>" ARGV[2]);
我需要将配置文件 1 合并到配置文件 2。如果文件 1 有文件 2 没有,则将其附加到文件 2 的末尾。我可以用系统替换打印以修复错误,但我不知道为什么打印不起作用。
使用print i"=" a[i] >> ARGV[2];
,未能将文本追加到文本末尾
1.txt,注意第三行是空行:
key=5678
abc=000
- txt:
key=1234
test.awk:
#!/usr/bin/env -S gawk -F= -f
{
key = gensub(/\s/, "", "g", );
if (NR==FNR) {
a[key]=;
} else {
b[key]=;
}
}
END{
for (i in a) {
if (b[i] == "") {
print "bi = empty, append to end of file:" i"="a[i];
print i"="a[i] >> ARGV[2];
# system("echo " i "=" a[i] ">>" ARGV[2]);
} else if (a[i] != b[i]) {
cmd = sprintf("sed -i -r 's@\s*(%s)\s*=.*@\1=%s@' %s", i, a[i], ARGV[2]);
system(cmd);
}
}
}
运行 ./test.awk 1.txt 2.txt 结果:
$ ./test.awk 1.txt 2.txt
bi = empty, append to end of file:=
bi = empty, append to end of file:abc=000
$ cat 2.txt
key=5678
=
为什么 abc=000 没有添加到 2.txt?如果改成system("echo" i "=" a [i] ">" argv [2]),又OK了,是不是print有bug?
在gnu awk手册中,“5.9关闭输入和输出重定向”,需要调用close函数,当多个命令操作同一个文件时,例如pipe或cmd, 太糟糕了,所以我放弃打印>>,只使用system()。
最后,我使用这个脚本:
#!/usr/bin/env -S gawk -F"=|is" -f
# File: sync_kernelconfig.awk
# Author: Edward.Tang
# Mail: edaplayer@163.com
# Function: 同步文件1的内核配置到文件2
function set_value(array, comment, k, v)
{
if (!/^\s*#/) {
array[k]=v;
} else {
comment[k]=;
}
}
{
key = gensub(/#|\s/, "", "g", );
if (key == "") next; # 跳过空行
if (NR==FNR) {
set_value(a1, c1, key, );
} else {
set_value(a2, c2, key, );
line[key] = [=14=]; # line data of file2
}
}
END {
for (i in a1) {
if (a2[i] == "") {
if (c2[i] == "") {
system("echo " i "=" a1[i] ">>" ARGV[2]);
} else {
cmd = sprintf("sed -i -r 's~%s~%s=%s~' %s", line[i], i, a1[i], ARGV[2]);
system(cmd);
}
} else if (a1[i] != a2[i]) {
cmd = sprintf("sed -i -r 's~%s~%s=%s~' %s", line[i], i, a1[i], ARGV[2]);
system(cmd);
}
}
for (i in c1) {
if (a2[i] != "") {
cmd = sprintf("sed -i -r 's~%s~# %s is%s~' %s", line[i], i, c1[i], ARGV[2]);
system(cmd);
}
}
}
gnu awk手册中的“5.9关闭输入输出重定向”,需要调用close函数,当多个命令操作同一个文件时,比如pipe或cmd,就很糟糕了
所以我需要使用:
print i"="a[i] >> ARGV[2];
close(ARGV[2]);
或:
system("echo " i "=" a1[i] ">>" ARGV[2]);