使用sed(或类似的东西)修改变量的内容

时间:2013-10-23 20:26:03

标签: bash sed

我写了一个BASH文件,其中包含多个

形式的嵌入循环
for P in {'0.10','0.20', [...] '0.90','1.00'}; do 
   for Q in {'0.10','0.20', [...] ,'0.90','1.00'}; do
    [...] 

我将这些变量用作命令行应用程序的参数,并直接在BASH中创建文件名。我想创建重复项,比如$P_REP=0_10,用一个下划线替换点,而不为每个案例写一个显式的switch语句,或者一些硬编码的等价物。我找到的(非优雅的方式)是

  1. P,Q的内容转储到临时文件。
  2. 使用sed 's/./_/ -i
  3. 用下划线替换点
  4. 再次读取文件并将其内容加载到新变量中。
  5. 因此,我想知道是否可以直接在变量的内容上运行sed like命令?

5 个答案:

答案 0 :(得分:17)

您可以直接在bash中进行模式替换:

P_REP=${P/./_}
Q_REP=${Q/./_}

来自bash(1)手册页:

  

Paramter Expansion

     

<强> ${parameter/pattern/string}

     

模式替换。扩展模式以生成模式,就像在路径名扩展中一样。 参数已展开, pattern 与其值的最长匹配将替换为 string 。如果 pattern /开头,则 pattern 的所有匹配项都将替换为 string 。通常只替换第一场比赛。如果 pattern #开头,则它必须在参数展开值的开头匹配。如果 pattern %开头,则它必须在参数展开值的末尾匹配。如果 string 为null,则删除 pattern 的匹配项,并且可以省略/ following pattern 。如果参数为@*,则替换操作依次应用于每个位置参数,并且扩展是结果列表。如果parameter是一个使用@*下标的数组变量,则替换操作将依次应用于数组的每个成员,并且扩展是结果列表。

答案 1 :(得分:11)

John Kugelman的答案适用于您的示例,但如果您需要使用实际的sed程序(或其他任意命令)处理变量的内容,您可以这样做:

P_REP=$(sed 's/\./_/' <<< "$P")

答案 2 :(得分:0)

For循环可以使用:

#!/bin/bash
P_REP=$(for P in '0.10' '0.20' '0.90' '1.00'; do echo ${P/./_} ; done)
Q_REP=$(for Q in '0.10' '0.20' '0.90' '1.00'; do echo ${Q/./_} ; done)

echo ${P_REP[@]}
echo ${Q_REP[@]}

答案 3 :(得分:0)

对于你提到的确切问题,请使用上面的约翰命题。

我会提到,如果你不得不做类似的事情,用bash的模式替换语法无法解决,你不需要实际创建临时文件来使用sed或类似命令转换内容。首先,您可以将变量作为STDIN直接传递给程序。其次,您可以将命令的输出(无论是STDOUT,STDERR还是两者)直接输入shell变量。

所以在你的例子中,你会有:

for P in 0.10 0.20 [...] 0.90 1.00 ; do 
   for Q in 0.10 0.20 [...] 0.90 1.00 ; do
        P_REP=$( sed 's/\./_/g' <<< "$P" )
        Q_REP=$( sed 's/\./_/g' <<< "$Q" )
   done
done

另请注意,数组语法(即{ '0.10', '0.20', ...})主要针对Bash和极少数Bash-followers。当你很容易这样做时,你可能更喜欢在shell中使用更经典的for循环方法,正如我在上面所说的那样。然后你的代码将安全地在所有符合posix的shell中执行。

答案 4 :(得分:0)

为什么这么复杂有简单的解决方案 您正在更改文件夹/目录中的所有子字符串所有文件

ORG="orignal_string"
DES="destination_string"
find . -type f -exec sed -i 's/'"${ORG}"'/'"${DES}"'/g' {} +