在awk、sed或python中基于值和键字符串合并行
我有以下输入表:在awk、sed或python中基于值和键字符串合并行,python,bash,sed,awk,Python,Bash,Sed,Awk,我有以下输入表: 1 2 A "aaa" 3 4 A "aaa" 5 6 A "aaa" 1 2 B "bbb" 3 4 B "bbb" 1 2 A "ccc" 我想得到: output1-从输入分别打印第1列和第2列中的最低值和最高值,并在第4列中使用相同的名称 1 6 A "aaa" 1 4 B "bbb" 1 2 A "ccc" output2-来自第1列和第2列“行之间”的输入
1 2 A "aaa"
3 4 A "aaa"
5 6 A "aaa"
1 2 B "bbb"
3 4 B "bbb"
1 2 A "ccc"
我想得到:
output1-从输入分别打印第1列和第2列中的最低值和最高值,并在第4列中使用相同的名称
1 6 A "aaa"
1 4 B "bbb"
1 2 A "ccc"
output2-来自第1列和第2列“行之间”的输入打印值;将第2列(第1行)和第1列(第2行)中的值放入第4列中具有相同名称的新行1(当第4列中的名称更改时跳过,如输入的第3、5、6行)
我非常感谢你的建议
提前谢谢 这里有一种使用
awk
awk '!b[$3" "$4]||b[$3" "$4]>$1 {b[$3" "$4]=$1} !t[$3" "$4]||b[$3" "$4]<$2 {t[$3" "$4]=$2} END {for (i in b) print b[i],t[i],i}' file
1 2 A "ccc"
1 6 A "aaa"
1 4 B "bbb"
awk'!b[$3”“$4]| | b[$3”“$4]>$1{b[$3”“$4]=$1}!t[$3”“$4]| b[$3”“$4]$1{b[$4]=$1}!在python中,您可以尝试以下解决方案。我对它进行了编辑,使它不仅能接受索引中的连续数字
# -*- encoding: utf-8 -*-
def get_min_max_index(data):
result = dict()
names = set([record[3] for record in data])
for name in names:
name_records = filter(lambda record: record[3] == name, data)
name_indices = map(lambda record: (record[0], record[1]), name_records)
record_id = name_records[0][2]
result[name] = (min(name_indices)[0], max(name_indices)[1], record_id, name_indices)
return result
def get_between_rows(data):
records_min_max = get_min_max_index(data)
result = list()
for i in range(len(data) - 1):
name = data[i][3]
max_ind = records_min_max[name][1]
if data[i][1] < max_ind:
result.append([data[i][1], data[i+1][0], data[i][2], data[i][3]])
return result
if __name__ == "__main__":
import sys
data = list()
for line in sys.stdin.readlines():
line = line.strip().split()
data.append([int(line[0]), int(line[1]), line[2], line[3].strip('"')])
for name, line in get_min_max_index(data).items():
print('{0} {1} {2} {3}'.format(line[0], line[1], line[2], name))
print('\n')
for line in get_between_rows(data):
print('{0} {1} {2} {3}'.format(line[0], line[1], line[2], line[3]))
# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4:
很多人都可以回答这个问题,但由于OP的努力不足,这里没有答案。很抱歉,我只是一个初学者,我尝试用awk中的一些单行程序来解决is,但没有真正的进展:(谢谢你的回答,它是这样做的,但考虑两栏3美元和4美元,我想只考虑撇号在4美元之间,即AAA或BBB与列<代码> 3”/代码>,如果它的变化,它不与<代码>第4版/代码>相同,那么打印什么,第一次点击,最后?我更新了我的帖子,没有列“3AWAK”!b[$4]| | b[$4]>$1{b[$4]=$1}!t[$4]| b[$4]$1{z[$4]=$3}结束{对于(b中的i)打印b[i],t[i],z[i],i}文件FielIT将工作,但只有字段3和4连接到相同的信息。谢谢,现在它完成了任务,你知道如何指定名称,而不是列4;如果列4中有多个值,我想在撇号中考虑一个,谢谢,抱歉,看起来我过于简化了示例,在实际数据中,数字是通常不是连续的,但对于第4列中的给定名称,它们总是增加(在省略号之间指定)请查看我的更新答案。我想你可以自己做一点努力:)再问一个问题;如果表中有更多的列,我只想按原样打印(假设在数字之前还有两列),这样做的最佳方法是什么;我不太明白第9行中记录id的解决方案:)结果[name]=(记录[0],记录[1],最小值(名称索引)[0],最大值(名称索引)[1],记录id,名称索引)?列表名称索引包含给定行的前两个值,由它指定。我调用name
行末尾的字符串,如aaa
,bbb
等。例如,第一行name\u索引将是(1,2)
。如果您希望在开始处有更多的列(比如说两个新列),这将把与record
相关的所有内容向右移动。例如,您将有(记录[2],记录[3])
在以name\u index=
开头的行上,而不是(记录[0],记录[1])
,因为您没有定义行:)
awk '!b[$4]||b[$4]>$1 {b[$4]=$1} !t[$4]||b[$4]<$2 {t[$4]=$2} {z[$4]=$3} END {for (i in b) print b[i],t[i],z[i],i}' file
1 6 A "aaa"
1 2 A "ccc"
1 4 B "bbb"
# -*- encoding: utf-8 -*-
def get_min_max_index(data):
result = dict()
names = set([record[3] for record in data])
for name in names:
name_records = filter(lambda record: record[3] == name, data)
name_indices = map(lambda record: (record[0], record[1]), name_records)
record_id = name_records[0][2]
result[name] = (min(name_indices)[0], max(name_indices)[1], record_id, name_indices)
return result
def get_between_rows(data):
records_min_max = get_min_max_index(data)
result = list()
for i in range(len(data) - 1):
name = data[i][3]
max_ind = records_min_max[name][1]
if data[i][1] < max_ind:
result.append([data[i][1], data[i+1][0], data[i][2], data[i][3]])
return result
if __name__ == "__main__":
import sys
data = list()
for line in sys.stdin.readlines():
line = line.strip().split()
data.append([int(line[0]), int(line[1]), line[2], line[3].strip('"')])
for name, line in get_min_max_index(data).items():
print('{0} {1} {2} {3}'.format(line[0], line[1], line[2], name))
print('\n')
for line in get_between_rows(data):
print('{0} {1} {2} {3}'.format(line[0], line[1], line[2], line[3]))
# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4:
1 6 A aaa
1 4 B bbb
1 2 A ccc
2 3 A aaa
4 5 A aaa
2 3 B bbb