我知道这对你们中的一个大师来说真的很容易!
我有一个这样的清单:
www.google.com
ebay.com
yahoo.com
www.bing.com
www.buy.com
woot.com
news.google.com
images.google.com
我正在尝试编写一个bash / sed / awk脚本来清理这个列表。 我需要列表看起来像这样:
www.google.com
www.ebay.com
www.yahoo.com
www.bing.com
www.buy.com
www.woot.com
news.google.com
images.google.com
总之,它需要添加“www。”如果它还没有www或子域。此列表位于名为theList的文件中。我蹩脚的尝试是这样的:
sed 's/^www\./' theList > cleanedList
这显然不适用于已经有www或子域的情况。 任何想法都将不胜感激。
谢谢!
EV
答案 0 :(得分:1)
使用awk比使用sed更容易。例如:
awk -F. 'NF == 2 {print "www." $0; next}; {print}' theList > cleanedList
这定义了"子域"作为名称中少于两个点的任何内容,使用点作为每个记录中的字段分隔符。你当然可以调整它以适应。
正确处理提供的语料库,如下所示:
$ cat cleanedList
www.google.com
www.ebay.com
www.yahoo.com
www.bing.com
www.buy.com
www.woot.com
news.google.com
images.google.com
答案 1 :(得分:1)
在bash中,你可以这样写:
while read; do
case "$REPLY" in
www.*|*.*.*) # begins with www. or contains at least two dots...
echo "$REPLY" # ...leave as-is
;;
*) # all other cases...
echo "www.$REPLY" # ...prepend "www."
;;
esac
done < theList > cleanedList
外部while循环从stdin读取(在最后一行重定向到theList
),一次一行。如果没有其他参数,该行将以shell变量$REPLY
结束。
case语句类似于C的switch语句,但它与通配符模式而不是整数常量进行比较。我们使用它将行($REPLY
)分为两类:一类不需要www.
前置,另一类不需要。{/ p>
第一种模式(www.|*.*.*)
)实际上是两种选择:行匹配www.*
(即以www.
开头)或匹配*.*.*
(即它包含至少两个点(它们可能相邻,但这不是验证模板名称的模式),因为Unix中的*
也匹配.
s)。在这种情况下,我们只是在得到它时输出该行。
第二种模式(*)
)匹配所有内容,但仅在第一种模式不匹配时才选择。在这些情况下,我们输出"www.$REPLY"
,即。我们将www.
添加到刚刚阅读的行中。
他们一起实施你描述的算法。
答案 2 :(得分:1)
密钥位于the regex。它捕获所有没有子域的独立域,然后将其替换为www.
及其自身。
sed -ri 's/^([^.]+\.[^.]+)$/www.\1/' YOUR_FILENAME
可替换地:
sed -r 's/^([^.]+\.[^.]+)$/www.\1/' YOUR_FILENAME > NEW_FILENAME