使用sed从一条线路中删除多条线路

使用sed从一条线路中删除多条线路,sed,Sed,sed中是否有某种方法可以从单个输入行创建多个输出行?我有一个模板文件(文件中有更多行,我只是简化它): 我目前正在使用sed将@PORT@替换为实际端口。但是,我希望能够传入多个端口,并为每个端口创建一条线路。可能吗?我假设您希望为每个端口号复制整行。在这种情况下,更容易将其视为用URL替换端口号: $ cat ports.in 1 2 3 4 5 $ sed 's#^\([0-9]*\$)#http://hostname:\1#' ports.in http://hostname:1 ht

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


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

我假设您希望为每个端口号复制整行。在这种情况下,更容易将其视为用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
这将同时读取
端口.in
url.in
,如果一行以数字开头,则假定它是
端口.in
中的端口号。否则,如果该行以
http
开头,则假定它是
URL.in
中的URL,并将端口占位符替换为
printf
格式字符串,然后为每次读取的端口号打印一次URL。如果文件以错误的顺序输入,它将无法做正确的事情

类似的解决方案,但从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

我假设您希望为每个端口号复制整行。在这种情况下,更容易将其视为用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
这将同时读取
端口.in
url.in
,如果一行以数字开头,则假定它是
端口.in
中的端口号。否则,如果该行以
http
开头,则假定它是
URL.in
中的URL,并将端口占位符替换为
printf
格式字符串,然后为每次读取的端口号打印一次URL。如果文件以错误的顺序输入,它将无法做正确的事情

类似的解决方案,但从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

似乎有多个模板和多个端口要应用于它们。下面介绍了如何在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是meta-sed脚本,因为它编写了另一个sed脚本。h将模式缓冲区保存在sed保持空间中。meta 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/

似乎有多个模板和多个端口要应用于它们。下面介绍了如何在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是meta-sed脚本,因为它编写了另一个sed脚本。h将模式缓冲区保存在sed保持空间中。meta 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/