如何让sed只更改每个字母的所有实例一次?

时间:2015-04-27 03:59:02

标签: bash sed associative-array caesar-cipher

到目前为止,代码只更改了第一个字母。如果我采取突破,那么它会多次更改一个字母的每个实例(这是不好的)。我只是尝试使用sed的凯撒密码。我意识到我可以使用tr来执行文本转换,但我更喜欢坚持使用sed。

echo "What number do you want to use for the shift?"
read num

declare -A origin

x=({a..z})

case "$num" in
    0)
    y=({a..z});;1)y=({{b..z},a});;2)y=({{c..z},a,b});;3)y=({{d..z},a,b,c});;4)y=({{e..z},a,b,c,d});;5)y=({{f..z},{a..e}});;
    6)y=({{g..z},{a..f}});;7)y=({{h..z},{a..g}})
    ;;
    8)
    y=({{i..z},{a..h}})
    ;;
    9)
    y=({{j..z},{a..i}})
    ;;
    10)
    y=({{k..z},{a..j}})
    ;;
    11)
    y=({{l..z},{a..k}})
    ;;
    12)
    y=({{m..z},{a..l}})
    ;;
    13)
    y=({{n..z},{a..m}})
    ;;
    14)
    y=({{o..z},{a..n}})
    ;;
    15)
    y=({{p..z},{a..o}})
    ;;
    16)
    y=({{q..z},{a..p}})
    ;;
    17)
    y=({{r..z},{a..q}})
    ;;
    18)
    y=({{s..z},{a..r}})
    ;;
    19)
    y=({{t..z},{a..s}})
    ;;
    20)
    y=({{u..z},{a..t}})
    ;;
    21)
    y=({{v..z},{a..u}})
    ;;
    22)
    y=({{w..z},{a..v}})
    ;;
    23)
    y=({{x..z},{a..w}})
    ;;
    24)
    y=({{y..z},{a..x}})
    ;;
    25)
    y=({{z..z},{a..y}})
    ;;
    *)
    echo "Sorry, you must use a shift from 0 to 25."
    ;;
esac

for i in {0..25}
do
    origin[${x[i]}]=${y[i]}
done

for i in {0..25}
do
    origin[${x[i]}]=${y[i]}
done

for a in "${!origin[@]}"
do
    for x in "${!origin[@]}"
    do
        sed -i 's/'${x}'/'${origin[${x}]}'/g' test.txt
        break
    done
done

3 个答案:

答案 0 :(得分:1)

以下执行凯撒密码(第3班):

sed -i y/$(printf "%s" {a..z})/$(printf "%s" {d..z} {a..c})/ test.txt

解释

y是sed的翻译命令。 $(printf "%s" {a..z})返回一串字符。要了解这一切是如何结合在一起的,请使用echo。它显示了bash执行扩展后的最终sed命令:

$ echo sed -i y/$(printf "%s" {a..z})/$(printf "%s" {d..z} {a..c})/ test.txt
sed -i y/abcdefghijklmnopqrstuvwxyz/defghijklmnopqrstuvwxyzabc/ test.txt

使用此命令,a的每次出现都会被d替换,b的每次出现都会被替换为e,依此类推。

可变班次

以下脚本采用一个参数,一个整数。然后它为该整数执行Caesar移位:

#!/bin/bash
alpha=$( printf "%s" {a..z} )
part1=$( printf $(printf '\%03o' $(seq $((97+$1)) 122 ) ) )
part2=$( printf $(printf '\%03o' $(seq 97 $((97+$1-1)) ) ) )
sed -i y/$alpha/$part1$part2/ test.txt

例如,假设我们有这个输入文件:

$ cat test.txt
and abc xyz 

让我们进行4班制:

$ bash script.sh 4
$ cat test.txt
erh efg bcd

答案 1 :(得分:1)

此代码通过命令行对Caesar Cypher进行测试:

#!/usr/bin/env bash
declare -i n=$1
file=$2

alphabet="abcdefghijklmnopqrstuvwxyz"
key="${alphabet:n}${alphabet:0:n}"

sed -i -e "y/${alphabet}/${key}/" ${file}

你这样使用它:

$ ./caesar.sh 4 test.txt

答案 2 :(得分:0)

#!/bin/bash

#This shit works:

echo "What number do you want to use for the shift?"
read num

declare -A origin

x=({a..z})

case "$num" in
    0)
    y=({a..z})
    ;;
    1)
    y=({{b..z},a})
    ;;
    2)
    y=({{c..z},a,b})
    ;;
    3)
    y=({{d..z},a,b,c})
    ;;
    4)
    y=({{e..z},a,b,c,d})
    ;;
    5)
    y=({{f..z},{a..e}})
    ;;
    6)
    y=({{g..z},{a..f}})
    ;;  
    7)
    y=({{h..z},{a..g}})
    ;;
    8)
    y=({{i..z},{a..h}})
    ;;
    9)
    y=({{j..z},{a..i}})
    ;;
    10)
    y=({{k..z},{a..j}})
    ;;
    11)
    y=({{l..z},{a..k}})
    ;;
    12)
    y=({{m..z},{a..l}})
    ;;
    13)
    y=({{n..z},{a..m}})
    ;;
    14)
    y=({{o..z},{a..n}})
    ;;
    15)
    y=({{p..z},{a..o}})
    ;;
    16)
    y=({{q..z},{a..p}})
    ;;
    17)
    y=({{r..z},{a..q}})
    ;;
    18)
    y=({{s..z},{a..r}})
    ;;
    19)
    y=({{t..z},{a..s}})
    ;;
    20)
    y=({{u..z},{a..t}})
    ;;
    21)
    y=({{v..z},{a..u}})
    ;;
    22)
    y=({{w..z},{a..v}})
    ;;
    23)
    y=({{x..z},{a..w}})
    ;;
    24)
    y=({{y..z},{a..x}})
    ;;
    25)
    y=({{z..z},{a..y}})
    ;;
    *)
    echo "Sorry, you must use a shift from 0 to 25."
    ;;
esac

fromset=""
toset=""

for i in {0..25}
do
    fromset="$fromset${x[i]}"
    toset="$toset${y[i]}"
done

sed "y/$fromset/$toset/" original.txt > encoded.txt
sed "y/$toset/$fromset/" encoded.txt > decoded.txt