我有 2 个具有以下结构的文件:
文件1:
# Some comments on the file
# I am a line
# I am a new line
# I am yet a new line
# A value in the next line
123
Values
(
1
2
3
4
5
)
文件2:
# Some comments on the file
# I am a line
# I am a new line
# A value in the next line
123
Values
(
1.1
2.1
3.1
4.1
5.1
)
预期结果将是一个具有绝对差异的文件
0.1
0.1
0.1
0.1
0.1
我想知道两个文件之间括号中的值之间的绝对差异。
目前我有一个功能:
foo()
{
paste $1 $2 | awk -F'\t' 'function abs(x){return ((x < 0.0) ? -x : x)} {print abs($1 - $2)}' > outputFile
}
这有效,但会检查所有文件。如果我的标题不匹配,我会遇到问题。有没有办法告诉 awk 在找到左括号后只应用函数?
此致
答案1
您已经知道如何创建和使用abs()
函数,因此只需将其添加到此:
$ awk '
/\(/{f=1; next} /)/{f=0} !f{next}
NR==FNR { file1[++a]=$0; next }
{ print $0 - file1[++b] }
' file1 file2
0.1
0.1
0.1
0.1
0.1
答案2
像这样:
foo() {
paste $1 $2 | awk -F'\t' '
function abs(x){return ((x < 0.0) ? -x : x)}
/\(/{f=1}
/\)/{f=0}
(f) {print abs($1 - $2)}
' > outputFile
}
答案3
笔记:如果注释包含括号,则需要进行额外处理。它们可以提前删除或跳过。
变体 1 号
awk -F'\n' '
function abs(n) {
return (n < 0) ? -n : n
}
NR == 2 {
for(i = 2; i < NF; i++) {
arr[i] = $i
}
}
NR == 5 {
for(i = 2; i < NF; i++) {
print abs(arr[i] - $i)
}
}
' RS='[)(]' file_1.txt file_2.txt
解释
RS='[)(]'
用括号而不是换行符分隔记录。因此,对于这样的例子:
some text\nValues(\nnum1\nnum2\nnum3\n...)\n
结果将是(括号消失):
record1 record2 record3
some text\nValues \nnum1\nnum2\nnum3\n... \n
-F'\n'
用换行符分隔字段。分裂记录2看起来是这样的:
'empty' num1 num2 num3 ...
field1 field2 field3 field4 ...
变种 2
awk '
function abs(n) {
return (n < 0) ? -n : n
}
!/\)/{
print abs($1 - $2)
}
' <(paste -d' ' <(sed '1,/(/d' file_1.txt) <(sed '1,/(/d' file_2.txt))
答案4
sed -n -e '/(/,/)/p' file1|sed -e '1d' -e '$d' >file1_1
sed -n -e '/(/,/)/p' file2|sed -e '1d' -e '$d' >file2_1
paste file1_1 file2_1| awk '{print $2-$1}' >file3
输出
cat file3
0.1
0.1
0.1
0.1
0.1