今天有个小需求,用 awk 和 sed 貌似不能很好的完成任务,打算转战 perl 了

2018-12-05 20:38:20 +08:00
 hujianxin

有一个文件,a.txt ,文容如下:

0689LM  name=S:321, password=154adfv839473, value=37461278216723
1633LM  name=S:241, password=15sdf78839611, value=21
1121LM  name=S:673, password=1543978839612, value=1230
1212LM  name=S:854, password=fd43978df9621, value=383242544
3323LM  name=S:456, password=sd9788396sdd3, value=11211
3322LM  name=S:234, password=dsfas78839623, value=23121
4238LM  name=S:254, password=1fdsafdsafdsa, value=324342
51LM    name=S:903, password=fdsafsdafsdaf, value=43543
2389LM  name=S:572, password=fdsfdsdfwefff, value=2343235
91452LM name=S:842, password=sdfwef23dffds, value=3434324
9553LM  name=S:fed, password=23fdssfdss32f, value=10501342176

需求:输出第一列的反转,name=S:之后的数字,value 之后的数值,如下:

ML9860 321 37461278216723
ML3361 241 21
ML1211 673 1230
ML2121 854 383242544
ML3233 456 11211
ML2233 234 23121
ML8324 254 324342
ML15 903 43543
ML9832 572 2343235
ML25419 842 3434324
ML3559 fed 10501342176

awk,不好实现第一列的反转

sed,不好显示抓取 name=S:之后的数字(需要非贪婪)

当然,也可能是我才疏学浅,如果各位大佬有更好的解决方法,欢迎指教。

perl -aE '/name=S:(.*?),.*?value=(.*)/; $a = reverse $F[0]; say "$a $1 $2"' a.txt

6779 次点击
所在节点    程序员
86 条回复
hawhaw
2018-12-06 16:38:06 +08:00
perl 还是太老了
但这货实在是强大
几乎啥场景都能找到包
直接用
urmyfaith
2018-12-06 16:47:29 +08:00
![]( )

你们要到 Excel
ltux
2018-12-06 16:49:57 +08:00
这种问题本来就是 Perl 的强项,awk sed 之类的工具本来压根本就不用学,一门 Perl 走天下即可。 上面说写了后来看不懂的,你写 sed awk 过几天照样看不懂。
hujianxin
2018-12-06 16:52:17 +08:00
loopfor
2018-12-06 16:53:58 +08:00
我觉得这种还是 java/c#/c++顺手。
那些一两行的看似精简,但是可维护性可读性都很差呀,出点问题调试也很麻烦。
araraloren
2018-12-06 17:04:56 +08:00
@loopfor 但是不是所有东西都需要维护的。。这东西就是用完就扔,下次再写
yiyizym
2018-12-06 17:20:00 +08:00
用 awk,自定义一个反转函数:rev

awk 'function rev(str){if(str == "") return ""; else return (rev(substr(str,2)) substr(str,1,1))} {print rev($1), substr($2,8), substr($4,7)}' a.txt
hujianxin
2018-12-06 17:30:59 +08:00
@yiyizym 可惜 awk 没有自带一个这种函数
yiyizym
2018-12-06 17:32:12 +08:00
@yiyizym

第二列多了个逗号,而且把 fed 也算进去了,更正一下:
awk 'function rev(str){if(str == "") return ""; else return (rev(substr(str,2)) substr(str,1,1))} {print rev($1), gensub(/[^0-9]/,"","g",$2), substr($4,7)}' a.txt
hellolleh
2018-12-06 18:00:10 +08:00
why not python?
lululau
2018-12-06 18:17:22 +08:00
说 Python 的可以试试能不能一分钟之内写出代码来,是的,像这样的不太复杂的文本处理任务用 Perl 一分钟之内就可以写出来代码

说 Excel 的可以试试算个一千万行或者更大的文本试试?

Perl 相比 sed / awk 的优势是,你不许区分 perl 还是 gperl,不许记哪些选项和功能是只有 GNU 版本的才有,不需要去区分 basic regex, extended regex, posix regex,你只要会 Perl 正则就可以了

sed 算是门艺术,偶尔写一下可以陶冶情操,贴一个 sed 实现 rev 的代码,陶冶一下😀

sed '/\n/!G;s/\(.\)\(.*\n\)/&\2\1/;//D;s/.//'
hujianxin
2018-12-06 18:25:14 +08:00
@lululau 这个很陶冶情操,手工再见
Raymon111111
2018-12-06 18:52:02 +08:00
哎呀 java 也可以其实(手动斜眼
no1xsyzy
2018-12-06 19:24:40 +08:00
@hujianxin “脑子混乱”并不是指我,而是写出 shell 的人。
一会想要以简短的字符表明一个意思,比如$+一个字符的那些(这不查那大部头 manual 根本不知道意思);
一会又不允许简洁地表达,比如单引号的处理(如何在单引号的引用字符串内放一个单引号?先结束前一段单引号字符串,反斜杠转义一个单引号进去,再开启下一段单引号字符,1->4 比反引号地狱还快)。

这纯是由于 shell 根本不是固定的一个人写的,甚至不是为了同一个目的设计的特性。
毫无主见地随波逐流地写特性出来。
只因为“之前有这个特性所以我们还是要保留这个特性”。
向后兼容只会造成过去的麻烦依旧堆积在那边。
hujianxin
2018-12-06 19:27:01 +08:00
@no1xsyzy oneliner 的话,没有这种问题,因为它根本不需要维护,用完就扔了
no1xsyzy
2018-12-06 19:32:35 +08:00
@lululau ……能,连 re 都不用
x=input()之后用 split 爆,一行内分别是
''.join(reversed(x.split(" ")[0]))
x.split("name=S:")[1].split(",")[0]
x.split(", value=")[-1]
用 print 输出
然后因为任意多行的要求,整个框在 while True 里面
总共写了 40 多秒
no1xsyzy
2018-12-06 19:34:24 +08:00
@hujianxin 那就不是“ shell 作为编程语言”的情况
shell 的 oneliner 并不能处理什么东西
zhuangjia
2018-12-06 20:14:53 +08:00
@xingheng 学习了
shyrock
2018-12-06 20:21:18 +08:00
@lululau emmm。。。这比较方法。。。是 m20p 比冰箱的显示分辨率高的比法?
Kirscheis
2018-12-06 20:27:02 +08:00
import re

n = re.compile(r'''name=S:(.{3})''')
m = re.compile(r'''value=(\d*)''')

with open('asdf','r') as f:
s = f.readlines()

for i in s:
a,b,c,d = i.split()
a = a[::-1]
b = n.match(b).groups()[0]
d = m.match(d).groups()[0]
print(a, b ,d)


python,写了 30 秒左右吧。

不是说 perl 这些不好,我个人认为新的这些脚本语言的一个优点是,即使没有接触过编程的人,也能大概猜出来它想干什么,因此在过些年过气之后,不至于让大家都觉得遗留的脚本是天书。

这是一个专为移动设备优化的页面(即为了让你能够在 Google 搜索结果里秒开这个页面),如果你希望参与 V2EX 社区的讨论,你可以继续到 V2EX 上打开本讨论主题的完整版本。

https://www.v2ex.com/t/514702

V2EX 是创意工作者们的社区,是一个分享自己正在做的有趣事物、交流想法,可以遇见新朋友甚至新机会的地方。

V2EX is a community of developers, designers and creative people.

© 2021 V2EX