由于这个线程的主要目的是如何在非 GNU awk 中进行就地保存,所以我首先发布它的模板,这将帮助任何有任何要求的人,他们需要添加/附加 BEGIN 和 @987654323 @ 部分在他们的代码中保持他们的主要块按照他们的要求,然后它应该进行就地编辑:
注意: 以下会将其所有输出写入 output_file,因此如果您想将任何内容打印到标准输出,请仅添加 print... 语句而不添加 > (out)在下面。
通用模板:
awk -v out_file="out" '
FNR==1{
close(out)
out=out_file count++
rename=(rename?rename ORS:"") "mv \047" out "\047 \047" FILENAME "\047"
}
{
.....your main block code.....
}
END{
if(rename){
system(rename)
}
}
' *.txt
提供的具体示例解决方案:
我在awk 本身中提出了以下方法(对于添加的示例,以下是我解决此问题并将输出保存到 Input_file 本身的方法)
awk -v out_file="out" '
FNR==1{
close(out)
out=out_file count++
rename=(rename?rename ORS:"") "mv \047" out "\047 \047" FILENAME "\047"
}
{
print FNR > (out)
}
END{
if(rename){
system(rename)
}
}
' *.txt
注意:这只是将编辑后的输出保存到 Input_file(s) 本身的测试,可以在他们的程序中使用它的 BEGIN 部分以及它的 END 部分,主要部分应该按照具体问题本身的要求。
公平警告:此外,由于这种方法会在路径中生成一个新的临时输出文件,因此更好地确保我们在系统上有足够的空间,尽管在最终结果中这将保持只有主要的 Input_file(s),但在操作期间它需要系统/目录上的空间
以下是对上述代码的测试。
用一个例子执行程序:让我们假设以下是.txt Input_file(s):
cat << EOF > test1.txt
onetwo three
tets testtest
EOF
cat << EOF > test2.txt
onetwo three
tets testtest
EOF
cat << EOF > test3.txt
onetwo three
tets testtest
EOF
现在当我们运行以下代码时:
awk -v out_file="out" '
FNR==1{
close(out)
out=out_file count++
rename=(rename?rename ORS:"") "mv \047" out "\047 \047" FILENAME "\047"
}
{
print "new_lines_here...." > (out)
}
END{
if(rename){
system("ls -lhtr;" rename)
}
}
' *.txt
注意:我有意将ls -lhtr 放在system 部分中,以查看它正在创建哪些输出文件(临时),因为稍后它会将它们重命名为他们的真实姓名。
-rw-r--r-- 1 runner runner 27 Dec 9 05:33 test2.txt
-rw-r--r-- 1 runner runner 27 Dec 9 05:33 test1.txt
-rw-r--r-- 1 runner runner 27 Dec 9 05:33 test3.txt
-rw-r--r-- 1 runner runner 38 Dec 9 05:33 out2
-rw-r--r-- 1 runner runner 38 Dec 9 05:33 out1
-rw-r--r-- 1 runner runner 38 Dec 9 05:33 out0
当我们在awk 脚本运行完成后执行ls -lhtr 时,我们只能看到.txt 文件。
-rw-r--r-- 1 runner runner 27 Dec 9 05:33 test2.txt
-rw-r--r-- 1 runner runner 27 Dec 9 05:33 test1.txt
-rw-r--r-- 1 runner runner 27 Dec 9 05:33 test3.txt
说明:在此处添加上述命令的详细说明:
awk -v out_file="out" ' ##Starting awk program from here, creating a variable named out_file whose value SHOULD BE a name of files which are NOT present in our current directory. Basically by this name temporary files will be created which will be later renamed to actual files.
FNR==1{ ##Checking condition if this is very first line of current Input_file then do following.
close(out) ##Using close function of awk here, because we are putting output to temp files and then renaming them so making sure that we shouldn't get too many files opened error by CLOSING it.
out=out_file count++ ##Creating out variable here, whose value is value of variable out_file(defined in awk -v section) then variable count whose value will be keep increment with 1 whenever cursor comes here.
rename=(rename?rename ORS:"") "mv \047" out "\047 \047" FILENAME "\047" ##Creating a variable named rename, whose work is to execute commands(rename ones) once we are done with processing all the Input_file(s), this will be executed in END section.
} ##Closing BLOCK for FNR==1 condition here.
{ ##Starting main BLOCK from here.
print "new_lines_here...." > (out) ##Doing printing in this example to out file.
} ##Closing main BLOCK here.
END{ ##Starting END block for this specific program here.
if(rename){ ##Checking condition if rename variable is NOT NULL then do following.
system(rename) ##Using system command and placing renme variable inside which will actually execute mv commands to rename files from out01 etc to Input_file etc.
}
} ##Closing END block of this program here.
' *.txt ##Mentioning Input_file(s) with their extensions here.