- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
下面是我的文件的样子(按 $3
排序):
name_1|G1026|2017-08-27|2017-08-27|2017-09-02|19|19|21
name_2|G1566|2018-05-05|2018-05-05|2018-06-11|51|51|2B
name_2|G2124|2018-06-11|2018-06-11|2018-06-11|51|19|2B
name_2|G2125|2018-06-11|2018-06-11|2018-06-15|51|19|41
name_1|G4391|2020-08-14|2020-08-14|2020-08-20|19|19|21
name_1|G4392|2020-08-14|2020-08-20|2020-08-20|19|51|21
字段分隔符是|
.我正在尝试添加一个额外的列 $9
基于现有列添加到此文件。对于 $1
中的多个名称实例,我想应用以下条件:
cond1 && (cond2 || cond3 || cond4) && (!cond5)
让prev
和 cur
是具有相同第一个字段、非空第三个字段和 cur
的两行以下 prev
.第 1、5 或 5、6 行是具有第一个字段 name_1
的此类行对。 .第 2,3 行和第 3,4 行是具有第一个字段 name_2
的此类行对。 .
让delta = number-of-days(prev.$5 - cur.$4)
是天数prev.$5
过去cur.$4
.
条件是:
cond1 = (0 <= delta <= 2 days)
例如,对于 name_1
的第一个实例(第一行),检查是否prev.$5
第一个实例(第一行)在 0 到 2 天后 cur.$4
来自第二个实例(第 6 行)。
cond2 = (prev.$6 == 51)
cond3 = (cur.$7 == 51)
cond4 = (cur.$8 == "2B" || cur.$8 == 41)
cond5 = (prev.$6 == 19 && cur.$7 == 51 && cur.$8 == 21)
如果满足这些条件,则添加列 $9
到两行中的第一行,因此输出将如下所示。
name_1|G1026|2017-08-27|2017-08-27|2017-09-02|19|19|21
name_2|G1566|2018-05-05|2018-05-05|2018-06-11|51|51|2B|group1
name_2|G2124|2018-06-11|2018-06-11|2018-06-11|51|19|2B|group2
name_2|G2125|2018-06-11|2018-06-11|2018-06-15|51|19|41
name_1|G4391|2020-08-14|2020-08-14|2020-08-20|19|19|21
name_1|G4392|2020-08-14|2020-08-20|2020-08-20|19|51|21
添加的列以group1
开头.每次添加列时,前导数字都会递增。
如果要求prev.$
和 cur.$
值在一行中,然后我可以应用以下代码:
awk -F "|" '{if ($1=="name_1" && (($5-$4)<=2) && ($6==51||$7==51||$8==2B|41) &&($6!=19 && $7!=51 && $8!=21)) print $9="group1"}' OFS="|"
文件
有关如何使用 awk
解决此问题的任何线索将不胜感激!
最佳答案
以下需要 GNU awk 扩展(mktime
):
$ cat foo.awk
function d2ts(d) {
gsub(/-/, " ", d)
return mktime(d " 0 0 0")
}
BEGIN {
f8["2B"] = 1;
f8["41"] = 1;
}
FNR == NR {
if($1 in ts && (f6[$1] == 51 || $7 == 51 || $8 in f8) &&
!(f6[$1] == 19 && $7 == 51 && $8 == 21)) {
delta = ts[$1] - d2ts($4)
if(delta >= -12*3600 && delta <= 60*3600)
change[nr[$1]] = 1
}
ts[$1] = d2ts($5)
f6[$1] = $6
nr[$1] = NR
next
}
{
if(FNR in change)
$(NF+1) = "group" ++cnt
print
}
$ awk -F'|' -f foo.awk OFS='|' file file
name_1|G1026|2017-08-27|2017-08-27|2017-09-02|19|19|21
name_2|G1566|2018-05-05|2018-05-05|2018-06-11|51|51|2B|group1
name_2|G2124|2018-06-11|2018-06-11|2018-06-11|51|19|2B|group2
name_2|G2125|2018-06-11|2018-06-11|2018-06-15|51|19|41
name_1|G4391|2020-08-14|2020-08-14|2020-08-20|19|19|21
name_1|G4392|2020-08-14|2020-08-20|2020-08-20|19|51|21
我们分两个阶段进行,file
被传递两次的原因。第一遍检查所有条件并将要修改的记录编号存储在关联数组 change
中。第二阶段将最后一列添加到所有记录中,该数字是 change
关联数组的键。
Note: in order to account for daylight savings time and leap seconds the date comparison does not use 0 and 2 days thresholds but minus half a day (
-12*3600
) and 2 days and a half (60*3600
). As your date fields have only a 1 day resolution this should behave as expected.
解释:
d2ts 函数将 YYYY-MM-DD
日期转换为 UNIX 时间戳,即自 1970/01/01 以来的秒数。这是通过首先使用 gsub
将 YYYY-MM-DD
转换为 YYYY MM DD
(空格而不是 -
), 连接 0 0 0
表示小时、分钟、秒,然后使用 mktime
转换为 UNIX 时间戳。
由于您的算法引用过去的行,我们使用关联数组(ts
、f6
和 nr
)来存储有关最后遇到的具有给定字段 #1 值的行。键是字段 #1 的值 (name_X
),值分别是字段 #5 的 UNIX 时间戳、字段 #6 的值和记录号。
由于字段 #8 有多个候选值,我们在 BEGIN
部分定义了另一个关联数组 (f8
),并使用 in
运算符用于测试。
当然,根据您的文件,您可能会在第一阶段遇到内存问题。例如,如果您有数十亿个不同的 name_X
值,则可能需要进行一些调整以避免由于关联数组的大小而导致内存溢出。
关于AWK:基于现有列创建新列,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/68499930/
是否可以从 awk 文件执行另一个 awk 文件?使用 awk 文件我需要执行当前文件夹中的所有 awk 文件。是否可以在 awk 中进行此类操作? 最佳答案 是的你可以。您需要使用 system()
这是一个 awk 脚本,它尝试根据第一列设置两个文件的差异: BEGIN{ OFS=FS="\t" file = ARGV[1] while (getline < file)
awk 逐行处理文件。假设每一行操作不依赖于其他行,有没有办法让 awk 一次并行处理多行? 是否有任何其他文本处理工具可以自动利用并行性并更快地处理数据? 最佳答案 唯一试图提供 awk 并行实现的
我有文件: 结果.txt Apple fruits 10 20 30 Car vehicle 40 50 60 Book study 70 80 90 假设这里第 2 列是特征,第 3 列是最小值
就目前而言,这个问题不适合我们的问答形式。我们希望答案得到事实、引用或专业知识的支持,但这个问题可能会引起辩论、争论、投票或扩展讨论。如果您觉得这个问题可以改进并可能重新打开,visit the he
我对 awk 的行为感到惊讶表演时浮点数 计算。它导致我对表格数据进行错误计算。 $ awk 'BEGIN {print 2.3/0.1}' 23 0.1}' )。 那么我应该如何执行大于 (
为什么我在下面的例子中得到分隔符前后的空格? awk -F'^' '{print $1,":",$2}' SERVER_2012-02-29-12-15-00 3969 : 1272 3969 :
我有一个文件,其中每四行是这样的: HISEQ15:454:D27KKACXX:6:2316:16241:100283 1:N:0:GTTTCG (对于那些感兴趣的人,此文件包含DNA序列) 我需
你能帮我按 $2 列中的坐标合并行吗?有一系列坐标以一个为单位增长。我想输出 f.e. :第 1 行合并到第 4 行 9079811-9079814,之后没有系列,因此将其合并到另一行等。对于输入中的
大家好,我是 awk 的新手,我可以问一下我有这样的输入文件吗: # ABC DEFG value1 GH value2 GH value3 GH # BCF SQW value4 GH value5
大家好,我想问一下,我对awk中的括号{}感到非常困惑,就像我写了一段代码 { FNR == 3 { print $1 " age is " $2 } } 但它在外括号上给了我错误但没有在打印语
我想知道如何在 awk 中使用多行注释。到目前为止,我一直在使用 # 来评论一行。有人可以就此指导我。谢谢你。 最佳答案 AWK 中没有多行注释,但如果需要,您可以伪造它。这是一种至少适用于 GNU
关于AND逻辑运算符的一个基本问题。我试图根据第1列和第2列的值提取数据文件niveles.csv中的某些字段。我想写一个awk语句,说“当field1 = date和field2 = area然后打
以下命令按预期工作。 # some command | awk '/(\|\|\)/,/;/' create table todel1 (id int) max_rows=2 /*!*/; alter
我有一个日志文件,需要在服务器上“重播”。 它包含这样的条目: Request: query: EXEC prc_insert_customer @param0: 11
如何从制表符分隔的字符串中选择第一列? # echo "LOAD_SETTLED LOAD_INIT 2011-01-13 03:50:01" | awk -F'\t' '{prin
我正在尝试在目录中的多个文件的内容中执行一些 grep 并将我的 grep 匹配附加到单个文件中,在我的输出中我还想要一个包含文件名的列,以了解哪些文件条目已被拾取。我试图使用 awk 来实现相同的目
我想选择文件中第9列的绝对值小于500的行。列有时为正,有时为负。 awk -F'\t' '{ if ($9 output.bam 到目前为止这不起作用..互联网上的一轮告诉我,要使用绝对值,我们应
例如,假设我运行以下命令: gawk -f AppendMapping.awk Reference.tsv TrueInput.tsv 假设文件名会改变。在遍历第一个文件时,我想创建一个映射。 map
我正在使用这个命令; awk -v regex1='new[[:blank:]]+File\(' 'BEGIN{print "Regex1 =", regex1}' 这警告我; awk: warnin
我是一名优秀的程序员,十分优秀!