在sed中按字母顺序对变量进行排序

时间:2014-11-06 23:28:08

标签: linux bash sorting sed

简而言之,我有一个bash脚本,可以在字典中找到所有5个字母单词,并带有一个重复的字母。我用sed打印出重复的字母和不要的字母。我必须按字母顺序排列不重复的字母,我不太确定如何

这是我的sed;

sed 's/\(.*\)\(.\)\(.*\)\2\(.*\)/\1\2\3\2\4  \2   \1\3\4 /'

所以我需要通过将它们组合成一个读循环来排序\ 1 \ 3 \ 4

更新

grep '^[a-z][a-z][a-z][a-z][a-z]$' /usr/share/dict/words | 
grep '.*\(.\).*\1.*' |
grep -v '.*\(.\).*\1.*\1.*' |
grep -v '.*\(.\).*\(.\).*\1.*\2.*\1.*\2.*' |
grep -v '.*\(.\).*\(.\).*\1.*\2.*\2.*\1.*' |
grep -v '.*\(.\).*\(.\).*\1.*\1.*\2.*\2.*' |
sed 's/\(.*\)\(.\)\(.*\)\2\(.*\)/\1\2\3\2\4 \2 \1\3\4/' |
while read word dup nondup
    do sort -$nondup 
    front=$[nondup:1]
    middle=$[nondup:2]
    back=$[nondup:3]

    echo $word $dup $front$middle$back
done

2 个答案:

答案 0 :(得分:2)

有关5个字母单词的示例词典:

$ cat file
timey
terra
debby
ovolt
spell

现在,使用sed命令,让我们按非重复字母对输出进行排序:

$ sed 's/\(.*\)\(.\)\(.*\)\2\(.*\)/\1\2\3\2\4  \2   \1\3\4 /' file | sort -k3
timey
debby  b   dey 
spell  l   spe 
terra  r   tea 
ovolt  o   vlt 

sort -k3对第三列进行排序。

以上但也按字母顺序对非经常性字母进行排序

此解决方案添加了一个shell while循环,以便对非重复字母进行排序:

sed 's/\(.*\)\(.\)\(.*\)\2\(.*\)/\1\2\3\2\4  \2   \1\3\4 /' file | while read word rep non
do
    non=$(echo "$non" | grep -o . | sort |tr -d "\n")
    echo "$word $rep $non"
done | sort -k3

在同一输入上,这会产生输出:

timey  
terra r aet
debby b dey
spell l eps
ovolt o ltv

仅适用于教师的原始方法

如果我理解正确,你的导师会想要这样的事情:

sed 's/\(.*\)\(.\)\(.*\)\2\(.*\)/\1\2\3\2\4  \2   \1\3\4 /' file | 
while read word rep non
do
    [ "$non" ] || continue # skip any word that lacks a repeating letter
    front=${non:0:1}
    middle=${non:1:1}
    back=${non:2:1}
    if [[ "$front" < "$middle" ]] && [[ "$front" < "$back" ]]
    then
        [[ "$middle" < "$back" ]] && non=$front$middle$back || non=$front$back$middle
    elif [[ "$middle" < "$front" ]] && [[ "$middle" < "$back" ]]
    then
        [[ "$front" < "$back" ]] && non=$middle$front$back || non=$middle$back$front
    elif [[ "$back" < "$front" ]] && [[ "$back" < "$middle" ]]
    then
        [[ "$front" < "$middle" ]] && non=$back$front$middle || non=$back$middle$front
    else
        echo "ERROR"
    fi
    echo "$word $rep $non"
done | sort -k3

此方法需要bash

答案 1 :(得分:1)

您可以简单地修改sed command和管道以排序以最有效地对3个字符进行排序。除了约翰的回答之外,如果你的问题只想要对残余物进行分类:

sed -e 's/\(.*\)\(.\)\(.*\)\2\(.*\)/\1\3\4/' stack/dat/dicta.dat | sort

<强>输入

$ cat stack/dat/dicta.dat
aback
abaft
abase
abash
abask
abate

<强>输出:

$ sed -e 's/\(.*\)\(.\)\(.*\)\2\(.*\)/\1\3\4/' stack/dat/dicta.dat | sort
bck
bft
bse
bsh
bsk
bte

如果您希望对完整输出进行排序,那么使用选项sort调用原始sed之后的-k3是正确的方法。