来自sed的多行

时间:2016-07-05 22:00:13

标签: sed

在sed中是否有某种方法可以从单个输入行创建多个输出行?我有一个模板文件(文件中有更多行,我只是简化它):

http://hostname:@PORT@

我目前正在使用sed将@ PORT @替换为真正的端口。但是,我希望能够传入多个端口,并为每个端口创建一条线路。这可能吗?

2 个答案:

答案 0 :(得分:0)

我假设你想复制每个端口号的整行。在这种情况下,更容易将其视为用URL替换端口号:

$ cat ports.in
1
2
3
4
5

$ sed 's#^\([0-9]*\$)#http://hostname:\1#' ports.in
http://hostname:1
http://hostname:2
http://hostname:3
http://hostname:4
http://hostname:5

使用awk

可以更轻松地完成相反的操作
$ cat url.in
http://hostname:@PORT@

$ awk '/^[0-9]/ {ports[++i]=$0} /^http/ {sub(":@PORT@", ":%d\n"); for (p in ports) printf($0, ports[p])}' ports.in url.in
http://hostname:2
http://hostname:3
http://hostname:4
http://hostname:5
http://hostname:1

这会同时读取ports.inurl.in,如果一行以数字开头,则假定它是来自ports.in的端口号。否则,如果该行以http开头,则假定它是url.in的网址,并使用printf格式字符串替换端口占位符,然后打印一次网址读取每个端口号。如果文件以错误的顺序送入,它将无法做正确的事情。

类似的解决方案,但从shell变量中获取URL:

$ myurl="http://hostname:@PORT@"
$ awk -v url="$myurl" 'BEGIN{sub(":@PORT@", ":%d\n",url)} /^[0-9]/ {ports[++i]=$0} END {for (p in ports) printf(url, ports[p])}' ports.in
http://hostname:2
http://hostname:3
http://hostname:4
http://hostname:5
http://hostname:1

答案 1 :(得分:0)

您似乎有多个模板和多个端口可应用于它们。以下是如何在shell脚本(使用bash测试)中执行此操作,但如果您希望保持简单,则需要在两个sed执行中执行此操作,因为您有两个多值输入。它在数学上是模板和替换值的叉积。

ports='80
8080
8081'

templates='http://domain1.net:%PORT/
http://domain2.org:%PORT/
http://domain3.com:%PORT/'

meta="s/(.*)/g; s|%PORT|\1|p; /p"
sed="`echo \"$ports\" |sed -rn \"$meta\" |tr '\n' ' '`"
echo "$templates" |sed -rn "h; $sed"

shell变量 meta 是一个元sed脚本,因为它写了另一个sed脚本。 h将模式缓冲区保存在sed保持空间中。从每个端口的元调用,替换和打印生成的sed命令。这就是结果。

http://domain1.net:80/
http://domain1.net:8080/
http://domain1.net:8081/
http://domain2.org:80/
http://domain2.org:8080/
http://domain2.org:8081/
http://domain3.com:80/
http://domain3.com:8080/
http://domain3.com:8081/