我有一个这样的文件,即
A 10 20 bob.1 ID=bob.1;Parent=bob;conf=XF;Note=bob_v1
A 20 30 bob.2 ID=bob.2;Parent=bob;Note=bob_v1;conf=XF
使用下面的命令行,我将信息提取为conf的单独列。
sed -Ei 's/(.*conf=)([^;]*)(;.*)/\1\2\3\t\2/g' my_file
但是,如果conf的末尾有这个符号;有用。否则没有。在这两种情况下以及在放置制表符为空的情况下,如何修改脚本以提取模式?
A 10 20 bob.1 ID=bob.1;Parent=bob;conf=XF;Note=bob_v1 XF
A 20 30 bob.2 ID=bob.2;Parent=bob;Note=bob_v1;conf=XF XF
答案 0 :(得分:1)
您实际上可以删除;
:
sed -iE 's/(.*conf=)([^;]*)(.*)/\1\2\3\t\2/g' my_file
[^;]*
是一个否定的括号表达式,它将仅匹配0个或多个(由于*
而定),而不是;
字符,因此;
不是必须存在于模式本身中,前面的模式已经是“受限制的”。
请参见online sed
demo:
s="A 10 20 bob.1 ID=bob.1;Parent=bob;conf=XF;Note=bob_v1
A 20 30 bob.2 ID=bob.2;Parent=bob;Note=bob_v1;conf=XF"
sed -E 's/(.*conf=)([^;]*)(.*)/\1\2\3\t\2/g' <<< "$s"
输出:
A 10 20 bob.1 ID=bob.1;Parent=bob;conf=XF;Note=bob_v1 XF
A 20 30 bob.2 ID=bob.2;Parent=bob;Note=bob_v1;conf=XF XF
答案 1 :(得分:1)
能否请您按照awk
中的说明进行操作。
awk 'match($0,/conf=[^;]*/){print $0,substr($0,RSTART+5,RLENGTH-5);next} 1' Input_file
说明: 现在添加上述代码的说明。
awk ' ##Starting awk program here.
match($0,/conf=[^;]*/){ ##Using match function of awk to match regex from string conf= till semi colon comes.
print $0,substr($0,RSTART+5,RLENGTH-5) ##Printing current line and then sub-string whose starting point of RSTART+5 and ending point is RLENGTH-5
next ##next will skip all further statements from here.
} ##Closing BLOCK for match function here.
1 ##Mentioning 1 will print lines, those ones which are not having conf string match so it will simply print them.
' Input_file ##Mentioning Input_file name here.
输出如下。
A 10 20 bob.1 ID=bob.1;Parent=bob;conf=XF;Note=bob_v1 XF
A 20 30 bob.2 ID=bob.2;Parent=bob;Note=bob_v1;conf=XF XF
答案 2 :(得分:1)
每当您有name = value输入数据时,我发现创建表示该关系的数组(下面的f[name]=value
)最简单,最可靠,最灵活等,因此您可以按其名称访问值。根据{{1}}的含义:
in case it is empty to put tab
或:
$ awk -F'[[:space:];=]+' -v OFS='\t' '
{delete f; for (i=5; i<NF; i+=2) f[$i]=$(i+1); print $0, f["conf"]}
' file
A 10 20 bob.1 ID=bob.1;Parent=bob;conf=XF;Note=bob_v1 XF
A 20 30 bob.2 ID=bob.2;Parent=bob;Note=bob_v1;conf=XF XF
答案 3 :(得分:1)
您可以尝试Perl单线版
$.get('myapi/getfile?cachebreaker=' + Date.now());
或更短
myapi/getfile?cachebreaker=1553709710447
答案 4 :(得分:1)
我们不应该要求;
中的\3
,因为它已经在\2
的排除字符列表中进行了处理:
sed -Ei 's/(.*conf=)([^;]*)(.*)/\1\2\3\t\2/' my_file
如果需要与;
以外的其他字符作为分隔符,请将其包含在\2
的字符列表中。这样的字符可能是\t
还是空格?
sed -Ei 's/(.*conf=)([^;\t ]*)(.*)/\1\2\3\t\2/' my_file
答案 5 :(得分:1)
此问题所链接的问题或多或少地直接复制of my answer:
BEGIN { OFS = FS = "\t" }
function get_attrib_by_name(key, n,attrib,kv) {
# Split the attribute field on semi-colons.
n = split($5, attrib, ";")
# Loop over the attributes and split each on "=".
# When we've found the one we're looking for (by key name in "key"),
# return the corresponding value.
for (i = 1; i <= n; ++i) {
split(attrib[i], kv, "=")
if (kv[1] == key) {
return kv[2]
}
}
}
# Using the above function.
{
name = get_attrib_by_name("conf")
print $0, name
}
测试:
$ awk -f script.awk file.gff
A 10 20 bob.1 ID=bob.1;Parent=bob;conf=XF;Note=bob_v1 XF
A 20 30 bob.2 ID=bob.2;Parent=bob;Note=bob_v1;conf=XF XF