用于修复域列表的Bash脚本

时间:2012-06-15 21:28:34

标签: bash sed awk

我知道这对你们中的一个大师来说真的很容易!

我有一个这样的清单:

 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

3 个答案:

答案 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