我想对文件中的 url 列表(1 个 url/行)进行排序,这样如果 url 以www.
or开头m.
,则排序是在假设该部分不存在(或与排序无关)的情况下完成的。有什么建议么?
例子
facebook.com###page
fahrrad.de###userlike-popup
m.facebook.com##.cx
www.facebook.com##body
www.fahrrad.de###userlike-footerbar
排序后的文件如下所示
www.facebook.com##body
m.facebook.com##.cx
facebook.com###page
www.fahrrad.de###userlike-footerbar
fahrrad.de###userlike-popup
解释
facebook.com
优先fahrrad.de
于 c 在 h 之前www.facebook.com##body
m.facebook.com##.cx
如同b
之前一样先于.
m.facebook.com##.cx
facebook.com###page
如同.
之前一样先于#
www.fahrrad.de###userlike-footerbar
优先fahrrad.de###userlike-popup
于 f 位于 p 之前
答案1
您始终可以在要跳过的部分之后添加一个字符并从那里开始排序(然后删除该字符):
如果您sed
支持该-E
选项(最新版本的 GNUsed
会这样做,而旧版本会替代-r
,尽管这对非 GNU 实现的移植性较差):
<file sed -E 's/^(www\.|m\.)?/&:/' | sort -t: -k2 | sed 's/://'
awk
可移植的是,您可以使用or执行相同的操作perl
:
<file awk '{sub(/^(www\.|m\.)?/, "&:"); print}' | sort -t: -k2 | sed 's/://'
<file perl -pe 's/^(www\.|m\.)?/$&:/' | sort -t: -k2 | sed 's/://'
虽然使用 POSIX sed
,你总是可以这样做:
<file sed -e 's/^www\./&:/;t' -e 's/^m\./&:/;t' -e 's/^/:/' |
sort -t: -k2 | sed 's/://'
或者,您可以在不以Nor.
开头的行的开头添加 a ,并对第一个后面的部分进行排序:www.
m.
.
<file sed -e '/^www\./b' -e '/^m\./!s/^/./' | sort -t. -k2 | sed 's/^\.//'
答案2
单独使用perl
:
perl -e 'print sort {$a=~s/^(www|m)\.//r cmp $b=~s/^(www|m)\.//r} <>'
$a
和$b
是 Perl 中的特殊变量,允许指定自定义sort
比较
s/^(www|m)\.//r
将在应用之前从输入行中删除前导www.
或部分m.
sort
<>
在这种情况下将给出输入行数组
施瓦茨变换变体:
perl -e 'print map { $_->[0] }
sort { $a->[1] cmp $b->[1] or $a->[0] cmp $b->[0] }
map { [$_, s/^(www|m)\.//r] } <>'
同样,与ruby
:
# can golf it to {_1.sub(/^(www|m)\./, "")} on latest version
ruby -e 'puts readlines.sort_by {|s| s.sub(/^(www|m)\./, "")}'
答案3
让我们看看这个:
sed 's;^\([wm\.]*\)\(.*\)$;\2 \1\2;' file | sort | awk '{ print $2 }'