【问题标题】:How can I get sed to change all of the instances of each letter only once?我怎样才能让 sed 只更改每个字母的所有实例一次?
【发布时间】:2015-04-27 03:59:02
【问题描述】:

到目前为止,代码只更改了第一个字母。如果我采取突破,那么它会不止一次地更改一个字母的每个实例(这很糟糕)。我只是在尝试使用 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

【问题讨论】:

    标签: bash sed associative-array caesar-cipher


    【解决方案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,依此类推。

    变量移位

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

    #!/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
    

    【讨论】:

    • plus 1. 注意同样可以通过tr 命令实现。 & 也许tr 会比sed 更轻量级...
    【解决方案2】:

    此代码在命令行中执行 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
    

    【讨论】:

      【解决方案3】:
      #!/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
      

      【讨论】:

        猜你喜欢
        • 2022-08-20
        • 2020-11-28
        • 1970-01-01
        • 1970-01-01
        • 2021-04-25
        • 2022-01-16
        • 1970-01-01
        • 1970-01-01
        • 2018-02-04
        相关资源
        最近更新 更多