我有一个很大的数据集,如下所示:
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,那么我的输出文件应该包含最好的行:
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 下一个最佳行
1 5 2 9 4 5 # because except (5-4), both (5-1) and (9-2) are > 2我目前的方法是读取每一行,将每个字段保存为一个变量,做减法。但我不知道如何继续下去。
谢谢,
发布于 2012-11-10 17:08:08
将"best“行打印到文件" best”,并将"next best“行打印到文件"nextbest”
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。如果(
threshold,则将该行的fail_count递增为零,这意味着它属于“最佳”行。否则,如果该行的fail_count为1,则它属于“下一个最佳”行。
发布于 2012-11-10 02:27:17
这里有一个很棒的方法:
#!/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用法:
$ ./script.sh 2 yourFile.txt
2 5 3 7 1 6
4 8 1 8 6 9然后,可以很容易地重定向此输出:
$ ./script.sh 2 yourFile.txt > output.txt注意:如果您在每个line...But之间有那些空行,这将不能正常工作,我相信上面的操作会让您更好地工作。
发布于 2012-11-10 01:30:44
在狂欢中我可能不会这么做。就我个人而言,我会用Python来做这件事,这通常对那些小的快速和肮脏的脚本很好。
如果您的数据在文本文件中,您可以阅读here,了解如何将数据作为行列表放入Python中。然后您可以使用for循环来处理每一行:
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)https://stackoverflow.com/questions/13312772
复制相似问题