例如,输入:
line1 col1-1 http://www.google.com/index.html col3-1 col4 col5 col6 col7 col8
line2 col1-2 https://user:pwd@www.facebook.com/pp/index.html col3-2 col4 col5 col6 col7 col8
line3 col1-3 badColumn col3-3 col4 col5 col6 col7 col8
应导致
line1 col1-1 http://www.google.com col3-1 col4 col5 col6 col7 col8
line2 col1-2 https://www.facebook.com col3-2 col4 col5 col6 col7 col8
line3 col1-3 badColumn col3-3 col4 col5 col6 col7 col8
可以通过awk
一个线性(sub
和regex
?否则,您将如何在 bash 中实现它?
我认为使用 URL 解析器可能会更好。例如,Python 有:urlparse,可用于将 URL 解析为组件。下面是一些示例代码,如下所示:
python3 script.py file
script.py
内容:
import sys
import csv
from urllib.parse import urlparse
with open(sys.argv[1], 'r') as csvfile:
r = csv.reader(csvfile, delimiter=' ')
for row in r:
url = urlparse(row[2]);
if (url.scheme and url.hostname):
row[2] = url.scheme + "://" + url.hostname
print(' '.join(row))
结果:
line1 col1-1 http://www.google.com col3-1 col4 col5 col6 col7 col8
line2 col1-2 https://www.facebook.com col3-2 col4 col5 col6 col7 col8
line3 col1-3 badColumn col3-3 col4 col5 col6 col7 col8
有了GNU awk
你可以做到:
gawk '$3~/http/{$3=gensub(/([^/]+)//([^/]+).*/,"\1//\2","g",$3);gsub(///.*www/,"//www",$3)}1' file
$ cat file
line1 col1-1 http://www.google.com/index.html col3-1 col4 col5 col6 col7 col8
line2 col1-2 https://user:pwd@www.facebook.com/pp/index.html col3-2 col4 col5 col6 col7 col8
line3 col1-3 badColumn col3-3 col4 col5 col6 col7 col8
$ awk '$3~/http/{$3=gensub(/([^/]+)//([^/]+).*/,"\1//\2","g",$3);gsub(///.*www/,"//www",$3)}1' file
line1 col1-1 http://www.google.com col3-1 col4 col5 col6 col7 col8
line2 col1-2 https://user:pwd@www.facebook.com col3-2 col4 col5 col6 col7 col8
line3 col1-3 badColumn col3-3 col4 col5 col6 col7 col8
另一个awk
awk '/http/ {split($3,a,"/");sub(/^.*@/,"",a[3]);$3=a[1]"//"a[3]}8' file
line1 col1-1 http://www.google.com col3-1 col4 col5 col6 col7 col8
line2 col1-2 https://www.facebook.com col3-2 col4 col5 col6 col7 col8
line3 col1-3 badColumn col3-3 col4 col5 col6 col7 col8
不是最漂亮的正则表达式,但在 sed 中:
$ sed -r 's|://([^/]*@)?([^/]*)[^ t]*|://2|g' < myfile
line1 col1-1 http://www.google.com/ col8
line2 col1-2 https://user:pwd@www.facebook.com/ col8
line3 col1-3 badColumn col3-3 col4 col5 col6 col7 col8
"//user:password@"替换为"//"
sed 's:/.*@://:g' inputfile
我的快速和肮脏的sed解决方案是这样的:
sed 's#//[^@]*@#//#;s#([^/])/[^/][^ ]* #1 #' file1
与此处的其他列一样,它不会将其活动限制在第三列。 这依赖于这样一种想法,即 URL 中的第一个非双斜杠是您要开始剥离的位置,并且这些神奇的双斜杠不会出现在该行的其他任何地方。
将事情限制在第三列,awk 似乎是一个不错的选择。 但是你不能在大多数awk实现中使用sub()
或gsub()
函数进行反向引用,但你可以在GAWK的gensub()
中使用它们,就像这样:
gawk '{$3=gensub(///([^@/]+@)?([^/]+).*/, "//\2", "g", $3)} 1' file1
这与jaypal的解决方案类似,但比Jaypal的解决方案更简单,因为它只使用一个替换,并且它不需要"www"是主机名的一部分。
但你也可以在纯粹的 bash 中做到这一点:
while read one two three four; do
method=${three%//*}
host=${three#*//}
host=${host#*@}
host=${host%/*}
three="$method//$host"
echo "$one $two $three $four"
done < file1
是的。你可以在 bash 中做任何事情。 只是需要更多的打字。 :)