我的文本文件如下所示:
Liquid penetration 95% mass (m) = 0.000205348
Liquid penetration 95% mass (m) = 0.000265725
Liquid penetration 95% mass (m) = 0.000322823
Liquid penetration 95% mass (m) = 0.000376445
Liquid penetration 95% mass (m) = 0.000425341
现在我想Liquid penetration 95% mass (m)
从行中删除内容以仅获取值。我该怎么做?
答案1
如果只有一个=
标志,您可以删除其之前的所有内容,包括=
以下内容:
$ sed -r 's/.* = (.*)/\1/' file
0.000205348
0.000265725
0.000322823
0.000376445
0.000425341
如果要更改原始文件,请-i
经过测试后使用该选项:
sed -ri 's/.* = (.*)/\1/' file
笔记
-r
使用 ERE,这样我们就不必(
逃避)
s/old/new
old
用。。。来代替new
.*
任意数量的任意字符(things)
things
稍后使用 、 等保存以供\1
反向\2
引用。
答案2
这是一项工作awk
;假设值仅出现在最后一个字段中(根据您的示例):
awk '{print $NF}' file.txt
NF
是一个awk
变量,扩展为一条记录(行)中的字段数,因此$NF
(注意$
前面的)包含最后一个字段的值。
例子:
% cat temp.txt
Liquid penetration 95% mass (m) = 0.000205348
Liquid penetration 95% mass (m) = 0.000265725
Liquid penetration 95% mass (m) = 0.000322823
Liquid penetration 95% mass (m) = 0.000376445
Liquid penetration 95% mass (m) = 0.000425341
% awk '{print $NF}' temp.txt
0.000205348
0.000265725
0.000322823
0.000376445
0.000425341
答案3
我决定比较这里列出的不同解决方案。为此,我根据 OP 提供的内容创建了一个大文件:
我创建了一个简单的文件,名为
input.file
:$ cat input.file Liquid penetration 95% mass (m) = 0.000205348 Liquid penetration 95% mass (m) = 0.000265725 Liquid penetration 95% mass (m) = 0.000322823 Liquid penetration 95% mass (m) = 0.000376445 Liquid penetration 95% mass (m) = 0.000425341
然后我执行了这个循环:
for i in {1..100}; do cat input.file | tee -a input.file; done
终端窗口被阻塞了。我
killall tee
从另一个终端执行。然后我通过命令检查了文件的内容:less input.file
和cat input.file
。除了最后一行,它看起来还不错。所以我删除了最后一行并创建了一个备份副本:(cp input.file{,.copy}
因为命令使用到位选项)。文件中最终的行数
input.file
为2 192 473。我通过以下命令获取了该号码wc
:$ cat input.file | wc -l 2192473
比较结果如下:
-
$ time grep -o '[^[:space:]]\+$' 输入.文件 > 输出.文件 实际 0m58.539s 用户 0m58.416s 系统 0分0.108秒
-
$ time sed -ri 's/.* = (.*)/\1/' 输入.文件 实际 0m26.936s 用户 0m22.836s 系统 0 分 4.092 秒
或者,如果我们将输出重定向到新文件,命令会更快:
$ time sed -r 's/.* = (.*)/\1/' 输入.文件 > 输出.文件 实际 0分19.734秒 用户 0m19.672s 系统 0分0.056秒
gawk '{gsub(".*= ", "");print}'
$ time gawk '{gsub(".*= ", "");print}' 输入.文件 > 输出.文件 实际 0分5.644秒 用户 0分5.568秒 系统 0分0.072秒
-
$ time rev 输入.文件 | cut -d' ' -f1 | rev > 输出.文件 实际 0分3.703秒 用户 0分2.108秒 系统 0 分 4.916 秒
-
$ time grep -oP'.*= \K.*' 输入.文件 > 输出.文件 实际 0分3.328秒 用户 0分3.252秒 系统 0分0.072秒
sed 's/.*= //'
(该-i
选项分别使命令速度慢几倍)$ time sed 's/.*= //' 输入.文件 > 输出.文件 实际 0m3.310s 用户 0分3.212秒 系统 0分0.092秒
perl -pe 's/.*= //'
(-i
此处的选项不会对生产力产生很大的影响)$ time perl -i.bak -pe 's/.*= //' 输入.文件 实际 0分3.187秒 用户 0分3.128秒 系统 0分0.056秒
$ time perl -pe 's/.*= //' 输入.文件 > 输出.文件 实际 0分3.138秒 用户 0分3.036秒 系统 0 分 0.100 秒
-
$ time awk '{print $NF}' 输入.文件 > 输出.文件 实际 0分1.251秒 用户 0分1.164秒 系统 0分0.084秒
-
$ time cut -c 35- 输入.文件 > 输出.文件 实际 0分0.352秒 用户 0分0.284秒 系统 0分0.064秒
-
$ 时间切割-d=-f2输入文件 > 输出文件 实际 0分0.328秒 用户 0分0.260秒 系统 0分0.064秒
答案4
由于行前缀始终具有相同的长度(34 个字符),因此您可以使用cut
:
cut -c 35- < input.txt > output.txt