如何将数组变量传递给SED?

时间:2015-04-22 00:33:45

标签: arrays bash sed substitution

我正在尝试使用SED将Caesar Cipher转换为加密的文本文件。目前,我正在尝试使用两个数组,一个从a到z,另一个从z到a。但是,SED抛出了奇怪的错误(“sed:-e expression#1,char 3:unterminated`s s”命令。)

#!/bin/bash

#Substitute the inOrder with the reverseOrder

inOrder=();
reverseOrder=();

for w in {a..z}
do
    inOrder+=(${w})
done

for z in {z..a}
do
    reverseOrder+=(${z})
done

echo ${inOrder[@]}
echo ${reverseOrder[@]}

sed -i 's/'${inOrder[@]}'/'${reverseOrder[@]}'/g' new.txt

2 个答案:

答案 0 :(得分:1)

第一个问题是你没有将脚本参数保留为一个参数。

${inOrder[@]}a b c d ... y z。注意空格。当您将其替换为sed命令时,您会得到:

set -i 's/'a b c d ... y z'/'z y ... d c b a'/g/' new.txt

相同
set -i 's/a' b c d ... y 'z/z' y ... d c b 'a/g/' new.txt

所以你的脚本是s/a,处理一堆奇怪的文件(bcd,... y,{{ 1}}和z/z再次......和y目录)。在a/g/中,您可以看到替换命令未被终止。

这里你需要的是加倍引用以将扩展保持为一个参数:s/a"s/${inOrder[@]}..."

但是,这仍然无法解决您的任务,因为您尝试用反向字符串替换整个字符串's/'"$inOrder[@]"...,但可能在您的数据中找不到这样的字符串,因此它会失败。此外,Caesar Cypher涉及代替字母,而不是字母表。相反,您需要a b c d ... y z,它可以进行单字符替换。

tr

答案 1 :(得分:0)

我找到了符合我需求的解决方案。非常感谢你们的建议!

#!/bin/bash

#Retrieve the desired shift from user
echo "What number do you want to use for the shift?"
read num

#Create an array of all letters
x=({a..z})

#Take user input and use to create the cipher array
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

#create the string variables for manipulation
fromset=""
toset=""

#place the alphabetic arrays into the atring variables
for i in {0..25}
do
    fromset="$fromset${x[i]}"
    toset="$toset${y[i]}"
done

#Use sed text transformations to alter given files
sed "y/$fromset/$toset/" original.txt > encoded.txt
sed "y/$toset/$fromset/" encoded.txt > decoded.txt