Issue
I need merge config file1 to config file2. If file 1 has file 2 does not, append it to end of file2. I can replace print with system for fix bug, but i don't know why print didn't work.
Use print i"=" a[i] >> ARGV[2];
, failed to append text to the end of text
1.txt,Notice that the 3rd line is a blank line:
key=5678
abc=000
- txt:
key=1234
test.awk:
#!/usr/bin/env -S gawk -F= -f
{
key = gensub(/\s/, "", "g", $1);
if (NR==FNR) {
a[key]=$2;
} else {
b[key]=$2;
}
}
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);
}
}
}
run ./test.awk 1.txt 2.txt result :
$ ./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
=
Why is abc=000 not added to 2.txt? If it is changed to system ("echo" I "=" a [i] ">" argv [2]), and it is OK again, is there a bug in print?
In gnu awk manual, "5.9 Closing Input and Output Redirections", need call close function, when multiple commands operate on the same file,such as pipe or cmd, it's too bad, so i give up print >>, only use system().
Finally, i use this script:
#!/usr/bin/env -S gawk -F"=|is" -f
# File: sync_kernelconfig.awk
# Author: Edward.Tang
# Mail: [email protected]
# Function: 同步文件1的内核配置到文件2
function set_value(array, comment, k, v)
{
if (!/^\s*#/) {
array[k]=v;
} else {
comment[k]=$2;
}
}
{
key = gensub(/#|\s/, "", "g", $1);
if (key == "") next; # 跳过空行
if (NR==FNR) {
set_value(a1, c1, key, $2);
} else {
set_value(a2, c2, key, $2);
line[key] = $0; # 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);
}
}
}
Solution
In gnu awk manual, "5.9 Closing Input and Output Redirections", need call close function, when multiple commands operate on the same file,such as pipe or cmd, it's too bad.
So i need use:
print i"="a[i] >> ARGV[2];
close(ARGV[2]);
or:
system("echo " i "=" a1[i] ">>" ARGV[2]);
Answered By - Edward Answer Checked By - Mary Flores (WPSolving Volunteer)