String 如何基于字符串特征保留凌乱表中的值
我有一个非常困难的file.asv(用@分隔的值),其中包含不匹配列的行 例如:String 如何基于字符串特征保留凌乱表中的值,string,awk,sed,String,Awk,Sed,我有一个非常困难的file.asv(用@分隔的值),其中包含不匹配列的行 例如: name@age@city@lat@long eric@paris@4.4283333333333331e+01@-1.0550000000000000e+02 dan@43@berlin@3.1366000000000000e+01@-1.0371500000000000e+02 london@@2.5250000000000000e+01@1.0538333000000000e+02 纬度和经度值相当一致。它
name@age@city@lat@long
eric@paris@4.4283333333333331e+01@-1.0550000000000000e+02
dan@43@berlin@3.1366000000000000e+01@-1.0371500000000000e+02
london@@2.5250000000000000e+01@1.0538333000000000e+02
纬度和经度值相当一致。它们有22或23个字符(取决于正负号),并且总是带有科学符号。我只想保留每条线的纬度和经度
预期产出:
lat@long
4.4283333333333331e+01@-1.0550000000000000e+02
3.1366000000000000e+01@-1.0371500000000000e+02
2.5250000000000000e+01@1.0538333000000000e+02
标题不是完全必要的,我可以稍后添加它们。我还可以使用分离的纬度和经度输出,然后将它们粘贴在一起。我可以使用任何sed或awk命令吗?使用此
awk
:
awk 'BEGIN{OFS=FS="@"} {print $(NF-1),$NF}' file
这里,
-输出字段分隔符OFS
-输入字段分隔符FS
-字段数NF
纬度
和经度
始终是最后一个字段$NF
和$(NF-1)
将打印最后两个字段
测试:
$ awk 'BEGIN{OFS=FS="@"} {print $(NF-1),$NF}' file
lat@long
4.4283333333333331e+01@-1.0550000000000000e+02
3.1366000000000000e+01@-1.0371500000000000e+02
2.5250000000000000e+01@1.0538333000000000e+02
使用此
awk
:
awk 'BEGIN{OFS=FS="@"} {print $(NF-1),$NF}' file
这里,
-输出字段分隔符OFS
-输入字段分隔符FS
-字段数NF
纬度
和经度
始终是最后一个字段$NF
和$(NF-1)
将打印最后两个字段
测试:
$ awk 'BEGIN{OFS=FS="@"} {print $(NF-1),$NF}' file
lat@long
4.4283333333333331e+01@-1.0550000000000000e+02
3.1366000000000000e+01@-1.0371500000000000e+02
2.5250000000000000e+01@1.0538333000000000e+02
尝试使用正则表达式选择字段
$ cat ll.awk
function rep(c, n, ans) { # repeat `c' `n' times
while (n--) ans = ans c
return ans
}
function build_re( d, s, os) { # build a regexp `r'
d = "[0-9]" # a digit
s = "[+-]" # sign
os = s "?" # optional sign
r = os d "[.]" rep(d, 16) "e" s d d # adjust here
r = "^" r "$" # match entire string
}
function process( sep, line, i) {
for (i = 1; i <= NF; i ++ ) {
if (!($i ~ r)) continue # skip fields
line = line sep $i; sep = FS
}
if (length(line)) print line
}
BEGIN {
build_re()
FS = "@"
}
{ # call on every line of input
process()
}
尝试使用正则表达式选择字段
$ cat ll.awk
function rep(c, n, ans) { # repeat `c' `n' times
while (n--) ans = ans c
return ans
}
function build_re( d, s, os) { # build a regexp `r'
d = "[0-9]" # a digit
s = "[+-]" # sign
os = s "?" # optional sign
r = os d "[.]" rep(d, 16) "e" s d d # adjust here
r = "^" r "$" # match entire string
}
function process( sep, line, i) {
for (i = 1; i <= NF; i ++ ) {
if (!($i ~ r)) continue # skip fields
line = line sep $i; sep = FS
}
if (length(line)) print line
}
BEGIN {
build_re()
FS = "@"
}
{ # call on every line of input
process()
}
在Gnu awk中使用
gensub
再增加一个:
$ awk '{print gensub(/(.+)((@[^@]+){2})$/,"\\2","g",$0)}' file
@lat@long
@4.4283333333333331e+01@-1.0550000000000000e+02
@3.1366000000000000e+01@-1.0371500000000000e+02
@2.5250000000000000e+01@1.0538333000000000e+02
在Gnu awk中使用
gensub
再增加一个:
$ awk '{print gensub(/(.+)((@[^@]+){2})$/,"\\2","g",$0)}' file
@lat@long
@4.4283333333333331e+01@-1.0550000000000000e+02
@3.1366000000000000e+01@-1.0371500000000000e+02
@2.5250000000000000e+01@1.0538333000000000e+02
简单的
grep
就可以了,假设存在-o
选项
$ grep -o '[^@]*@[^@]*$' file.asv
lat@long
4.4283333333333331e+01@-1.0550000000000000e+02
3.1366000000000000e+01@-1.0371500000000000e+02
2.5250000000000000e+01@1.0538333000000000e+02
简单的
grep
就可以了,假设存在-o
选项
$ grep -o '[^@]*@[^@]*$' file.asv
lat@long
4.4283333333333331e+01@-1.0550000000000000e+02
3.1366000000000000e+01@-1.0371500000000000e+02
2.5250000000000000e+01@1.0538333000000000e+02
请提供上述项目的预期产出file@fibar请参见提供上述内容的预期输出file@fibar看见