英文:
Replacing a character in awk
问题
我正在使用以下命令对文件进行操作:
awk '{delta = $1 - avg; avg += delta / NR; mean2 += delta * ($1 - avg); } END { print avg" "sqrt(642)*sqrt(mean2 / NR); }' param_A_ratio_re_truncated.txt
现在,我想一次性重复执行此命令行,但将文件名中的“A”替换为“D、G、K、M”等其他字符,而不是每次都键入该行。虽然我可以替换文件名中的数值,但我不确定如何更改字符。任何建议将不胜感激。谢谢。
英文:
I am using the following command to do a manipulation on a file:
awk '{delta = $1 - avg; avg += delta / NR; mean2 += delta * ($1 - avg); } END { print avg" "sqrt(642)*sqrt(mean2 / NR); }' param_A_ratio_re_truncated.txt
Now, I want to repeat this command line at once but replace "A" in the file name with "D, G, K, M" etc. other than typing the line every time. While I can replace numerical values in a file name, I am not sure how to change a character. Any suggestions would be appreciated. Thank you.
答案1
得分: 5
你可以尝试:
awk '.....' param_[ADGKM]_ratio_re_truncated.txt
...但这将生成一个单一的平均值/平方根/均值输出(即,awk
脚本将处理所有文件作为一个大数据集)。
如果意图是为每个文件生成单独的平均值/平方根/均值,一个简单/快速的解决方案是:
for fname in param_[ADGKM]_ratio_re_truncated.txt
do
echo "######### 输入:${fname}"
awk '.....' "${fname}"
done
你可以使用单个 awk
脚本来处理所有文件 并且 为每个文件生成单独的平均值/平方根/均值,但这将需要更多的代码,例如:
function print_output() {
if (rowcnt > 0)
print FILENAME, avg, sqrt(642)*sqrt(mean2 / rowcnt)
delta = avg = mean2 = ""
rowcnt = 0
}
FNR==1 { print_output() }
{ rowcnt++
delta = $1 - avg
avg += delta / rowcnt
mean2 += delta * ($1 - avg)
}
END { print_output() }
注意:
- 如果不想显示每个文件的名称,请删除
'FILENAME,'
。 - 假设所有文件至少有一行输入,否则可能需要一些额外的逻辑来处理 '空' 文件。
- 由于没有示例输入和预期输出,无法测试。
- 我假设原作者的当前代码按预期工作(即,我没有尝试验证原作者的当前代码)。
英文:
You can try:
awk '.....' param_[ADGKM]_ratio_re_truncated.txt
... but this is going to generate a single avg/sqrt/mean output (ie, the awk
script will process all files as one big set of data).
If the intention is to generate a separate avg/sqrt/mean for each file, one easy/quick solution:
for fname in param_[ADGKM]_ratio_re_truncated.txt
do
echo "######### input: ${fname}"
awk '.....' "${fname}"
done
You can use a single awk
script to process all files and generate a separate avg/sqrt/mean for each file but it will require a bit more code, eg:
awk '
function print_output() {
if (rowcnt > 0)
print FILENAME, avg, sqrt(642)*sqrt(mean2 / rowcnt)
delta = avg = mean2 = "" # reset variables for next file
rowcnt = 0
}
FNR==1 { print_output() } # FNR==1 => new file so print results for previous file
{ rowcnt++
delta = $1 - avg
avg += delta / rowcnt
mean2 += delta * ($1 - avg)
}
END { print_output() } # print results for last file
' param_[ADGKM]_ratio_re_truncated.txt
NOTES:
- remove
'FILENAME,'
if you don't want to display each file's name - assumes all files have at least one line of input otherwise some additional logic may be needed to handle 'empty' files
- unable to test since there's no sample input nor expected output
- I'm assuming OP's current code works as expected (ie, I haven't attempted to validate OP's current code)
答案2
得分: 2
我建议查看BEGINFILE/ENDFILE,并牢记FNR
(文件内的行数)和NR
(全局行数)之间的区别,考虑以下示例。我有file1.txt
的内容如下:
1
2
3
file2.txt
的内容如下:
10
20
30
40
file3.txt
的内容如下:
100
200
300
400
500
如果想要显示每个文件的总和和记录数,可以执行以下命令:
awk 'BEGINFILE{total=0}{total+=$1}ENDFILE{print FILENAME, "total value is", total, "number of records is", FNR}' file1.txt file2.txt file3.txt
得到输出:
file1.txt total value is 6 number of records is 3
file2.txt total value is 100 number of records is 4
file3.txt total value is 1500 number of records is 5
(在GNU Awk 5.1.0中测试通过)
英文:
> I want to repeat this command line at once but replace "A" in the file
> name with "D, G, K, M" etc. other than typing the line every time
I suggest taking look at BEGINFILE/ENDFILE and keeping in mind difference between FNR
(number of row inside file) and NR
(global number of row), consider following example, I have file1.txt
with content
1
2
3
file2.txt
with content
10
20
30
40
file3.txt
with content
100
200
300
400
500
and want to show total and number of records in each file, then I could do
awk 'BEGINFILE{total=0}{total+=$1}ENDFILE{print FILENAME, "total value is", total, "number of records is", FNR}' file1.txt file2.txt file3.txt
getting output
file1.txt total value is 6 number of records is 3
file2.txt total value is 100 number of records is 4
file3.txt total value is 1500 number of records is 5
(tested in GNU Awk 5.1.0)
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论