首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >如何在bash中成对减去字段?

如何在bash中成对减去字段?
EN

Stack Overflow用户
提问于 2012-11-10 01:14:44
回答 5查看 654关注 0票数 3

我有一个很大的数据集,如下所示:

代码语言:javascript
复制
5 6 5 6 3 5
2 5 3 7 1 6
4 8 1 8 6 9
1 5 2 9 4 5

对于每一行,我想从第二个字段中减去第一个字段,从第四个字段中减去第三个字段,依此类推,以加深字段的数量(总是偶数)。然后,我想报告那些与所有配对的差值超过一定限制(例如2)的行。我还应该能够报告下一个最好的行,即其中一个成对比较未能达到限制,但所有其他对满足限制的行。

在上面的示例中,如果我将限制设置为2,那么我的输出文件应该包含最好的行:

代码语言:javascript
复制
2 5 3 7 1 6    # because (5-2), (7-3), (6-1) are all > 2
4 8 1 8 6 9    # because (8-4), (8-1), (9-6) are all > 2 

下一个最佳行

代码语言:javascript
复制
1 5 2 9 4 5    # because except (5-4), both (5-1) and (9-2) are > 2

我目前的方法是读取每一行,将每个字段保存为一个变量,做减法。但我不知道如何继续下去。

谢谢,

EN

回答 5

Stack Overflow用户

回答已采纳

发布于 2012-11-10 17:08:08

将"best“行打印到文件" best”,并将"next best“行打印到文件"nextbest”

代码语言:javascript
复制
awk '
{
        fail_count=0
        for (i=1; i<NF; i+=2){
                if ( ($(i+1) - $i) <= threshold )
                        fail_count++
        }
        if (fail_count == 0)
                print $0 > "best"
        else if (fail_count == 1)
                print $0 > "nextbest"
}
' threshold=2 inputfile

非常简单的东西。

一次循环通过字段2。如果(

  1. -
  2. )没有超过threshold,则将该行的fail_count递增为零,这意味着它属于“最佳”行。

否则,如果该行的fail_count为1,则它属于“下一个最佳”行。

票数 3
EN

Stack Overflow用户

发布于 2012-11-10 02:27:17

这里有一个很棒的方法:

代码语言:javascript
复制
#!/bin/bash

threshold=$1
shift
file="$@"

a=($(cat "$file"))
b=$(( ${#a[@]}/$(cat "$file" | wc -l) ))

for ((r=0; r<${#a[@]}/b; r++)); do
    br=$((b*r))
    for ((c=0; c<b; c+=2)); do

        if [[ $(( ${a[br + c+1]} - ${a[br + c]} )) < $threshold ]]; then
            break; fi

        if [[ $((c+2)) == $b ]]; then
            echo ${a[@]:$br:$b}; fi

    done
done

用法:

代码语言:javascript
复制
$ ./script.sh 2 yourFile.txt
2 5 3 7 1 6
4 8 1 8 6 9

然后,可以很容易地重定向此输出:

代码语言:javascript
复制
$ ./script.sh 2 yourFile.txt > output.txt

注意:如果您在每个line...But之间有那些空行,这将不能正常工作,我相信上面的操作会让您更好地工作。

票数 3
EN

Stack Overflow用户

发布于 2012-11-10 01:30:44

在狂欢中我可能不会这么做。就我个人而言,我会用Python来做这件事,这通常对那些小的快速和肮脏的脚本很好。

如果您的数据在文本文件中,您可以阅读here,了解如何将数据作为行列表放入Python中。然后您可以使用for循环来处理每一行:

代码语言:javascript
复制
threshold = 2
results = []
for line in content:
    numbers = [int(n) for n in line.split()] # Split it into a list of numbers
    pairs = zip(numbers[::2],numbers[1::2]) # Pair up the numbers two and two.
    result = [abs(y - x) for (x,y) in pairs] # Subtract the first number in each pair from the second.
    if sum(result) > threshold:
        results.append(numbers)
票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/13312772

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档