Awk - 在程序内排序数据 - 自定义日期时间戳
Awk - sort data inside program - custom datetime stamp
我正在使用 gawk 处理大型文本文件。我现在需要对文件中的列进行排序。是否可以使用 gawk 对包含日期时间戳的列进行排序?
第 2 列中显示的日期时间戳是用双引号括起来的“m/d/yy, H:M AM/PM
”。
1,”2/1/22, 9:25 AM",
2,"2/8/22, 11:03 AM",
3,"2/7/22, 8:57 AM",
4,"2/18/22, 5:50 PM",
5,"2/24/22, 9:11 AM",
6,"2/7/22, 1:59 PM",
7,"2/9/22, 7:34 AM",
8,"2/16/22, 7:14 AM",
9,"1/31/22, 5:53 PM",
我可以在 gawk 中对数据进行排序吗,这样我就可以插入第三列并将我的 table 设为
9,"1/31/22, 5:53 PM",1
1,”2/1/22, 9:25 AM",2
3,"2/7/22, 8:57 AM",3
6,"2/7/22, 1:59 PM",4
2,"2/8/22, 11:03 AM",5
7,"2/9/22, 7:34 AM",6
8,"2/16/22, 7:14 AM",7
4,"2/18/22, 5:50 PM",8
5,"2/24/22, 9:11 AM",9
这在 gawk 中可行吗?
假设文件大小不超过可用内存,请您尝试:
gawk '
# custom function to compare the timestamps
function date_sort(i1, v1, i2, v2, a1, a2, s1, s2) {
split(v1, a1, /[,"/: ]+/)
split(v2, a2, /[,"/: ]+/)
# generate strings of "yy-mm-dd (AM|PM) hh:mm"
s1 = sprintf("%02d-%02d-%02d %s %02d:%02d",
a1[4], a1[2], a1[3], a1[7], a1[5], a1[6])
s2 = sprintf("%02d-%02d-%02d %s %02d:%02d",
a2[4], a2[2], a2[3], a2[7], a2[5], a2[6])
# return the comparison result
if (s1 < s2) {
return -1
} else if (s1 > s2) {
return 1
} else {
return 0
}
}
# read the file and store lines in an array "data"
{data[NR] = [=10=]}
END {
# sort "data" using the function "date_sort" and store the result in "sorted"
n = asort(data, sorted, "date_sort")
for (i = 1; i <= n; i++) {
print sorted[i] i
}
}
' input_file
输出:
9,"1/31/22, 5:53 PM",1
1,"2/1/22, 9:25 AM",2
3,"2/7/22, 8:57 AM",3
6,"2/7/22, 1:59 PM",4
2,"2/8/22, 11:03 AM",5
7,"2/9/22, 7:34 AM",6
8,"2/16/22, 7:14 AM",7
4,"2/18/22, 5:50 PM",8
5,"2/24/22, 9:11 AM",9
asort
函数的第三个参数 "date_sort"
是自定义函数名称
比较要排序的列表。该函数应设计为 return 负值、正值或零,具体取决于
传递的两个元素的比较。在排序操作期间,四个参数被隐式传递给函数:
第一个列表元素的索引,第一个列表元素的值,
第二个列表元素的索引,第二个列表元素的值,按顺序排列。
按照惯例,我将它们命名为 i1
、v1
、i2
、v2
。
其余变量a1
、a2
、s1
、s2
为局部变量。
awk
的特点是变量列表比数字长
调用者传递的参数用于声明局部变量名以限制
函数内变量的范围。
我正在使用 gawk 处理大型文本文件。我现在需要对文件中的列进行排序。是否可以使用 gawk 对包含日期时间戳的列进行排序?
第 2 列中显示的日期时间戳是用双引号括起来的“m/d/yy, H:M AM/PM
”。
1,”2/1/22, 9:25 AM",
2,"2/8/22, 11:03 AM",
3,"2/7/22, 8:57 AM",
4,"2/18/22, 5:50 PM",
5,"2/24/22, 9:11 AM",
6,"2/7/22, 1:59 PM",
7,"2/9/22, 7:34 AM",
8,"2/16/22, 7:14 AM",
9,"1/31/22, 5:53 PM",
我可以在 gawk 中对数据进行排序吗,这样我就可以插入第三列并将我的 table 设为
9,"1/31/22, 5:53 PM",1
1,”2/1/22, 9:25 AM",2
3,"2/7/22, 8:57 AM",3
6,"2/7/22, 1:59 PM",4
2,"2/8/22, 11:03 AM",5
7,"2/9/22, 7:34 AM",6
8,"2/16/22, 7:14 AM",7
4,"2/18/22, 5:50 PM",8
5,"2/24/22, 9:11 AM",9
这在 gawk 中可行吗?
假设文件大小不超过可用内存,请您尝试:
gawk '
# custom function to compare the timestamps
function date_sort(i1, v1, i2, v2, a1, a2, s1, s2) {
split(v1, a1, /[,"/: ]+/)
split(v2, a2, /[,"/: ]+/)
# generate strings of "yy-mm-dd (AM|PM) hh:mm"
s1 = sprintf("%02d-%02d-%02d %s %02d:%02d",
a1[4], a1[2], a1[3], a1[7], a1[5], a1[6])
s2 = sprintf("%02d-%02d-%02d %s %02d:%02d",
a2[4], a2[2], a2[3], a2[7], a2[5], a2[6])
# return the comparison result
if (s1 < s2) {
return -1
} else if (s1 > s2) {
return 1
} else {
return 0
}
}
# read the file and store lines in an array "data"
{data[NR] = [=10=]}
END {
# sort "data" using the function "date_sort" and store the result in "sorted"
n = asort(data, sorted, "date_sort")
for (i = 1; i <= n; i++) {
print sorted[i] i
}
}
' input_file
输出:
9,"1/31/22, 5:53 PM",1
1,"2/1/22, 9:25 AM",2
3,"2/7/22, 8:57 AM",3
6,"2/7/22, 1:59 PM",4
2,"2/8/22, 11:03 AM",5
7,"2/9/22, 7:34 AM",6
8,"2/16/22, 7:14 AM",7
4,"2/18/22, 5:50 PM",8
5,"2/24/22, 9:11 AM",9
asort
函数的第三个参数 "date_sort"
是自定义函数名称
比较要排序的列表。该函数应设计为 return 负值、正值或零,具体取决于
传递的两个元素的比较。在排序操作期间,四个参数被隐式传递给函数:
第一个列表元素的索引,第一个列表元素的值,
第二个列表元素的索引,第二个列表元素的值,按顺序排列。
按照惯例,我将它们命名为 i1
、v1
、i2
、v2
。
其余变量a1
、a2
、s1
、s2
为局部变量。
awk
的特点是变量列表比数字长
调用者传递的参数用于声明局部变量名以限制
函数内变量的范围。