AWK 跳过行直到匹配字符然后执行计算

AWK 跳过行直到匹配字符然后执行计算

我有 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

相关内容