【问题标题】:How to invert a domain using regex?如何使用正则表达式反转域?
【发布时间】:2014-03-05 01:09:53
【问题描述】:

我正在尝试为我正在编写的几个使用唯一名称间距的脚本反转域。

所以输入看起来像example.com,输出是com.example;虽然是的,但我知道s/\(\w\+\).*\(\w\+\)$/\2.\1/ 方法,但要求是能够动态支持多个子域,因此静态'\2.\1' 不起作用。基于 BRE 的 POSIX REGEX 会是什么样子?

【问题讨论】:

  • 我还想指出,tac(1) 和 perl(1) 并不存在于所有 UNIX 机器上。因此在 OSX、BSD、HP/UX 和 Plan9 上不可靠。

标签: regex sed dns


【解决方案1】:

正则表达式不适合这项工作。有很多方法可以做到,这里是一种:

address=www.example.com
dotted=$(echo $address. | tac -s.)
reversed=${dotted%?}
echo $reversed
# => com.example.www

编辑:如果你坚持使用 sed 和正则表达式:

echo 'www.example.com' | sed 's/\([^.]*\)\(\.\?\)\([^.]*\)\(\.\?\)\([^.]*\)\(\.\?\)\([^.]*\)\(\.\?\)\([^.]*\)/\9\8\7\6\5\4\3\2\1/g'
# => com.example.www

但是,它最多可以处理五个组件 (a.b.c.d.e)。如果您想要便携性,jlhonora 的答案仍然是最好的。

【讨论】:

  • +1 令人印象深刻的使用(相对)晦涩的工具的晦涩选项。
  • 使用 tac(1) 很好,虽然脚本有点冗长。 bash 变量扩展 (${dotted%?}) 如何在您的示例中发挥作用?
  • @DwightSpencer: tac 将带有“line”的“line terminator”;所以x.y.z.可以变成z.y.x.,但是x.y.z变成zy.x.为了避免这个问题,我在tac前面加了一个点,用${...%?}后去掉。
  • 好吧,你得到了 +1,尽管这仍然不能回答问题;对不起。
  • 很酷的编辑,虽然我敢打赌可以使用正则表达式分组来浓缩?
【解决方案2】:

这可能对你有用(GNU sed):

sed -r 'G;:a;s/^\n//;s/^([^.\n]+)(\.*)(.*\n)/\3\2\1/;ta' file

这会附加一个换行符,然后在其后附加域的每个部分。

当最后一部分被附加后,换行符被删除。

【讨论】:

  • @polong 我喜欢你把它当作 sed oneliner。虽然,换行符过多。您对使用条件“?”有何看法?并分组“{2,}”?
  • @DwightSpencer 谢谢。换行符是防止循环永远结束的唯一标记。它代表基本情况。我不明白conditional '?' 声明。
  • 对不起,我的意思是限定符不是有条件的:regular-expressions.info/refrepeat.html
【解决方案3】:

你可以使用awk:

echo 'test.example.com' | awk -F '.' '{out=$1; for(i=2;i<=NF;i++){ out=$i"."out}; print out}'

【讨论】:

  • @jilhonora 我刚刚运行了您的示例,但它没有像我询问的那样输出“反转”这个词。如果我这样做 echo 'example.com' | ... 我得到 `example.com' 这应该是 com.example、com.example.test 或 com.example.www.app1(假设输入是 app1.www.example.com)
  • out"."$i 应该是$i"."out;就目前而言,它重建了原始行:)
【解决方案4】:

我会寻求一种具有数组和反向函数的语言:

perl -lpe '$_ = join ".", reverse split /\./' <<< "$domain"

【讨论】:

【解决方案5】:

这是一个awk,应该恢复一个 dns 名称:

awk -F\. '{for (i=NF;i>=1;i--) printf "%s"(i==1?RS:FS),$i}'

例子:

echo 'test.example.com.br' | awk -F\. '{for (i=NF;i>=1;i--) printf "%s"(i==1?RS:FS),$i}'
br.com.example.test

这适用于任何长度的 DNS 名称:

this.is.my.dns.name.com.gov.us

给予

us.gov.com.name.dns.my.is.this

【讨论】:

  • 我希望我能正确理解您的 awk 脚本。看起来您使用的是 .作为字段分隔符,然后遍历最后一个字段。从那里打印结果或字段分隔符。 ,$i 是如何发挥作用的?
  • for 循环使用变量i 计算从最后一个字段到第一个字段的每个字段,因此对于www.google.comi 将变为3 2 1。在变量前面使用$,给出相应的字段。所以在这里:i=2 然后$i 给出$2,它给出第二个字段google
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2010-12-05
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2010-10-31
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多