给出一个空格分隔的文件:
0.0 1:0.000000 2:1.000000 3:0.000000 4:0.000000 5:1.000000 6:0.000000 7:1.000000 8:1.000000 9:1.000000 10:1.000000 11:1.000000 12:1.000000 13:1.000000 14:1.000000 15:0.919033 16:1.000000 17:1.000000 18:1.000000 19:1.000000 20:0.000000 21:0.037771
0.0 1:0.000000 2:1.000000 3:0.000000 4:0.000000 5:1.000000 6:0.000000 7:1.000000 8:0.800000 9:0.666667 10:1.000000 11:0.800000 12:0.666667 13:1.000000 14:0.875000 15:0.874574 16:0.848662 17:0.901802 18:0.938795 19:0.903077 20:0.333332 21:0.196682
0.0 1:1.098612 2:1.000000 3:1.000000 4:0.000000 5:1.000000 6:0.000000 7:1.000000 8:0.800000 9:0.500000 10:0.000000 11:0.800000 12:0.500000 13:0.000000 14:0.909091 15:0.780985 16:0.792052 17:0.865396 18:0.863982 19:0.832962 20:0.000000 21:0.069470
0.0 1:0.000000 2:1.000000 3:0.000000 4:0.000000 5:1.000000 6:0.000000 7:1.000000 8:0.923077 9:0.909091 10:0.888889 11:0.923077 12:0.909091 13:0.888889 14:0.943396 15:0.923562 16:0.923871 17:0.949357 18:0.950790 19:0.944919 20:0.142857 21:0.140054
第一列都是0.0
,我们希望将第一列扔掉。然后对于每一列,有一个冒号将键与其值分开。而目标只是保持价值。
我可以在python
:
with io.open(infile, 'r') as fin:
for line in fin:
line = line.split()[1:]
line = '\t'.join([i.split(':')[1] for i in line])
print line
[OUT]:
0.000000 1.000000 0.000000 0.000000 1.000000 0.000000 1.000000 1.000000 1.000000 1.000000 1.0000001.000000 1.000000 1.000000 0.919033 1.000000 1.000000 1.000000 1.000000 0.000000 0.037771
0.000000 1.000000 0.000000 0.000000 1.000000 0.000000 1.000000 0.800000 0.666667 1.000000 0.8000000.666667 1.000000 0.875000 0.874574 0.848662 0.901802 0.938795 0.903077 0.333332 0.196682
1.098612 1.000000 1.000000 0.000000 1.000000 0.000000 1.000000 0.800000 0.500000 0.000000 0.8000000.500000 0.000000 0.909091 0.780985 0.792052 0.865396 0.863982 0.832962 0.000000 0.069470
0.000000 1.000000 0.000000 0.000000 1.000000 0.000000 1.000000 0.923077 0.909091 0.888889 0.9230770.909091 0.888889 0.943396 0.923562 0.923871 0.949357 0.950790 0.944919 0.142857 0.140054
但是在unix命令行上是如何实现的?(可能与sed
,awk
,perl -c
甚至python -c
或其他任何事情)想象一下它是一个大文件,所以请不要将整个文件加载到内存中,除非这是一个经济上的原因。
答案 0 :(得分:2)
使用GNU sed:
sed 's/^0.0 //;s/[0-9]\+:\([0-9.]\+\)/\1/g' file
输出:
0.000000 1.000000 0.000000 0.000000 1.000000 0.000000 1.000000 1.000000 1.000000 1.000000 1.000000 1.000000 1.000000 1.000000 0.919033 1.000000 1.000000 1.000000 1.000000 0.000000 0.037771 0.000000 1.000000 0.000000 0.000000 1.000000 0.000000 1.000000 0.800000 0.666667 1.000000 0.800000 0.666667 1.000000 0.875000 0.874574 0.848662 0.901802 0.938795 0.903077 0.333332 0.196682 1.098612 1.000000 1.000000 0.000000 1.000000 0.000000 1.000000 0.800000 0.500000 0.000000 0.800000 0.500000 0.000000 0.909091 0.780985 0.792052 0.865396 0.863982 0.832962 0.000000 0.069470 0.000000 1.000000 0.000000 0.000000 1.000000 0.000000 1.000000 0.923077 0.909091 0.888889 0.923077 0.909091 0.888889 0.943396 0.923562 0.923871 0.949357 0.950790 0.944919 0.142857 0.140054
如果您要“就地”修改文件,请添加sed的选项-i
。
两个以;
分隔的sed脚本:
s/^0.0 //
:从^
的行首(0.0
)开始搜索后跟空格并替换为空白
s/[0-9]\+:\([0-9.]\+\)/\1/g
:搜索范围+
至0
中的至少一个(9
)字符,后跟:
,后跟至少一个(+
)0
到9
或.
范围内的字符,并通过圆括号中的匹配部分替换它。\1
是对圆括号中匹配部分的后引用。g
表示将替换应用于正则表达式的所有匹配,而不仅仅是第一个匹配。对于带有here: +
的sed,必须转义特殊字符((
,)
,\
)。
更短的版本:
sed 's/^0.0 //;s/[0-9]\+://g' file
答案 1 :(得分:2)
awk
救援!
$ awk '{gsub("[^ ]*:","");sub("[^ ]* ","")}1' file
0.000000 1.000000 0.000000 0.000000 1.000000 0.000000 1.000000 1.000000 1.000000 1.000000 1.000000 1.000000 1.000000 1.000000 0.919033 1.000000 1.000000 1.000000 1.000000 0.000000 0.037771
0.000000 1.000000 0.000000 0.000000 1.000000 0.000000 1.000000 0.800000 0.666667 1.000000 0.800000 0.666667 1.000000 0.875000 0.874574 0.848662 0.901802 0.938795 0.903077 0.333332 0.196682
1.098612 1.000000 1.000000 0.000000 1.000000 0.000000 1.000000 0.800000 0.500000 0.000000 0.800000 0.500000 0.000000 0.909091 0.780985 0.792052 0.865396 0.863982 0.832962 0.000000 0.069470
0.000000 1.000000 0.000000 0.000000 1.000000 0.000000 1.000000 0.923077 0.909091 0.888889 0.923077 0.909091 0.888889 0.943396 0.923562 0.923871 0.949357 0.950790 0.944919 0.142857 0.140054
答案 2 :(得分:1)
awk
可以做到这一点:
// {
for(i=2; i<=NF; i++)
{
split($i, array, ":")
printf("%s\t", array[2])
}
printf("\n")
}
解释://
表示&#34;对于每一行&#34; (实际上,它匹配所有可能的字符序列),for
每个字段从2
到最后一个(NF
),split
i
:
上的字段并将每个部分存储在array
中(从1开始,因此array[2]
是第二部分)和printf
。在每一行的末尾,打印换行符。
修改强>
这是我的第一个答案,但我在删除每列的其他部分时略过了一点。
您可以使用cut
命令:例如,如果您只需删除第一列,则可以编写
cut -c2- yourfile
解释:-c
可让您选择要保留的列,2-
表示&#34;来自第二个&#34;。
答案 3 :(得分:1)
为什么不使用该模块:
use Text::CSV;
它已经提供了将CSV文件轻松解析为结构的功能,并且还以另一种方式将结构解析为CSV文件。
然后,您可以选择要保留或删除的列。
答案 4 :(得分:1)
使用perl很容易:
perl -ne 'print join ( "\t", m/:([\d\.]+)/g ),"\n"' file_to_parse
此:
-n
将其包裹在while ( <> ) {
循环中):
在m/:([\d\.]+)/g
之后提取数值(并重复执行此操作)。我假设digits and .
但实际上你可以m/:(\S+)/g
如果有任何非空白&#39}没问题(如你的例子)。:
,因此省略它输出:
0.000000 1.000000 0.000000 0.000000 1.000000 0.000000 1.000000 1.000000 1.000000 1.000000 1.000000 1.000000 1.000000 1.000000 0.919033 1.000000 1.000000 1.000000 1.000000 0.000000 0.037771
0.000000 1.000000 0.000000 0.000000 1.000000 0.000000 1.000000 0.800000 0.666667 1.000000 0.800000 0.666667 1.000000 0.875000 0.874574 0.848662 0.901802 0.938795 0.903077 0.333332 0.196682
1.098612 1.000000 1.000000 0.000000 1.000000 0.000000 1.000000 0.800000 0.500000 0.000000 0.800000 0.500000 0.000000 0.909091 0.780985 0.792052 0.865396 0.863982 0.832962 0.000000 0.069470
0.000000 1.000000 0.000000 0.000000 1.000000 0.000000 1.000000 0.923077 0.909091 0.888889 0.923077 0.909091 0.888889 0.943396 0.923562 0.923871 0.949357 0.950790 0.944919 0.142857 0.140054