2016-07-05 66 views
1

sed中有一些方法可以從單個輸入行創建多條輸出線嗎?我有一個模板文件(有多個文件中的行,我只是簡化IT):來自sed的多條線

http://hostname:@[email protected] 

我目前使用SED與實端口來代替PORT @ @。不過,我希望能夠通過多個端口,並且讓sed爲每個端口創建一行。那可能嗎?

回答

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:@[email protected] 

$ awk '/^[0-9]/ {ports[++i]=$0} /^http/ {sub(":@[email protected]", ":%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的URL,並將用printf格式化字符串替換端口占位符,然後爲讀取的每個端口號打印一次URL。如果以錯誤的順序輸入文件,它將無法做正確的事情。

類似的解決方案,但是從一個shell變量取的網址:

$ myurl="http://hostname:@[email protected]" 
$ awk -v url="$myurl" 'BEGIN{sub(":@[email protected]", ":%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 
0

看來你有多個模板和多個端口,以適用於他們。以下是如何在shell腳本中執行此操作(使用bash進行測試),但如果您想保持簡單,因爲您有兩個多值輸入,則需要在兩次執行中執行此操作。它在數學上是模板和替代值的交叉產物。

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變量是元sed腳本,因爲它把另一個sed腳本。 h將模式緩衝區保存在sed保存空間中。從元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/