我有一个包含以下信息的文件:
用户名:[电子邮件保护] 值一:xx:xx:xx:xx:xx:xx 值二:xx:xx:xx:xx:xx:xx:xx:xx:xx:xx:xx:xx:xx:xx:xx:xx 价值三:[电子邮件保护]@[xx:xx] [三个值的混合] 用户名:[电子邮件保护] 值一:mm:mm:mm:mm:mm:mm 值二:mm:mm:mm:mm:mm:mm:mm:mm:mm:mm:mm:mm:mm:mm:mm:mm:mm:mm 价值三:[电子邮件保护]@[xx:xx] [三个值的混合] 用户名:[电子邮件保护] 值一:yy:yy:yy:yy:yy:yy 值二:yy:yy:yy:yy:yy:yy:yy:yy:yy:yy:yy:yy:yy:yy 价值三:[电子邮件保护]@[xx:xx] [三个值的混合] 用户名:[电子邮件保护] 值一:zz:zz:zz:zz:zz:zz 值二:zz:zz:zz:zz:zz:zz:zz:zz:zz:zz:zz:zz:zz:zz:zz:zz 价值三:[电子邮件保护]@[xx:xx] [三个值的混合]
首先,我想过滤掉所有以 S 开头的用户名信息,并保留以 V 开头的用户名信息。之后,我想制作一个可以运行的 .sh 脚本。我想要做的是:
- 回显用户名
- 删除第三个值
- 运行命令 Hello,并在第一个和第二个值上使用开关 -One、Two 和 --Thanks -for -visiting。
因此,我的 .sh 文件将类似于此
echo 用户名:[电子邮件保护] 你好 -一 mm:mm:mm:mm:mm:mm:mm -二: mm:mm:mm:mm:mm:mm:mm:mm:mm:mm:mm:mm:mm:mm:mm:mm:mm --感谢 -访问 echo 用户名:[电子邮件保护] 你好,一号 zz:zz:zz:zz:zz:zz:zz -二号:zz:zz:zz:zz:zz:zz:zz:zz:zz:zz:zz:zz:zz:zz:zz:zz --感谢 -访问
我在 Youtube 上观看了有关 Sed 的整个视频系列,并阅读了这里的许多文章,试图编写一个可以生成我想要的脚本的脚本,但都失败了。您能告诉我如何编写这样的脚本吗?如果您能推荐一些新用户可以阅读的有关 sed(或 Awk 或 Perl)的网站/参考资料,我将不胜感激
请注意,“:”的数量对于值一和值二是静态的,这可能会以某种方式使用。我尝试使用它,但每次我只要求值一时都会得到两个值,但你比我更了解如何利用这一事实。
抱歉,问题太长了!如果不实现自动化,完成所有这些工作将花费太多时间,而且我完全沉浸在 Linux 世界(以及计算机世界!)
答案1
由于你的文件是结构化的,中间留有空行记录,我建议使用awk
或perl
段落模式。例如,使用
- 一个或多个空行作为记录分隔符
RS=
- 使用冒号或换行符作为字段分隔符
-F': |\n'
$2
然后,如果字段以以下内容开头,则打印所需信息V
:
awk -vRS= -F': |\n' '
$2 ~ /^V/ {
print "echo " $1 ": " $2;
print "Hello -One " $4, "-Two " $6 " --Thanks -for -visiting";
print "";
}' file
给予
echo Username: [email protected]
Hello -One mm:mm:mm:mm:mm:mm -Two mm:mm:mm:mm:mm:mm:mm:mm:mm:mm:mm:mm:mm:mm:mm --Thanks -for -visiting
echo Username: [email protected]
Hello -One zz:zz:zz:zz:zz:zz -Two zz:zz:zz:zz:zz:zz:zz:zz:zz:zz:zz:zz:zz:zz:zz --Thanks -for -visiting
答案2
您可以使用:
sed -rn '/Username: S/,/^$/d;s/Username/echo &/p;/one: /N;s/Value one: (.+)\n/Hello -One: \1/;s/Value two: (.+)/ -Two \1 --Thanks -for -visiting\n/p' file
或者更易读
sed -rn '{
/Username: S/,/^$/d
s/Username/echo &/p
/one: /N
s/Value one: (.+)\n/Hello -One: \1/
s/Value two: (.+)/ -Two \1 --Thanks -for -visiting\n/p
}' file | tee newfile
解释
-r
使用扩展的正则表达式,这样我们就不必转义()
或+
-n
在我们要求之前不要打印任何内容(这就是我们摆脱第三行的方法)/Username: S/,/^$/d
找到Username: S
,从那里读取直到空行,然后删除所有内容s/thing/&/
查找thing
并替换为自身/one: /N
找到one:
并阅读下一行,以便我们加入它们s/Value one: (.+)\n/
匹配项Value one:
以及它后面的所有字符,直到换行符 (\n
),我们需要删除换行符以连接行,并保存未知字符\1
反向引用保存的模式()
p
打印此行
(我已经学会了一些 sed-fu(我只是一个初学者)这里)