【问题标题】:In bash: a "sed" command of a $VARIABLE inside a for loop在 bash 中:for 循环中 $VARIABLE 的“sed”命令
【发布时间】:2016-07-27 11:32:24
【问题描述】:

我有一个包含这些行的文件:

s17 line linewidth 1.0
s18 line linewidth 1.0
.
.
.
s28 line linewidth 1.0

我想将这些行替换为:

 s17 line linewidth 2.0
 s18 line linewidth 2.0
 .
 .
 .
 s28 line linewidth 2.0

我已经用 bash 编写了这段代码:

 #!/bin/bash
 for VARIABLE in {17..28}
 do
   sed 's/s${VARIABLE} line linewidth 1\.0/s${VARIABLE} line linewidth 2\.0/g' ./band-structure-calcite.agr
 done

然后我通过创建bash change.sh > changed.txt 运行代码,但文件changed.txt 不包含这些修改。

如果您在我学习 bash 时帮助我并解释您的代码答案的语法,我将不胜感激

【问题讨论】:

  • 单引号不能插入变量,双引号可以。
  • 运行sed N 次效率低下并且会给你许多重复的输出行(每行的N 个副本,每个副本的一个 被适当地修改)。如果您只想在匹配这些数字(可能不是其他数字)的行上将1.0 更改为2.0,有更好的方法来做到这一点。
  • @choroba :我已将脚本更改为:sed "s/s${VARIABLE} line linewidth 1\.0/s${VARIABLE} line linewidth 2\.0/g" ./band-structure-calcite.agr,但它不起作用
  • @EtanReisner :...“如果您只想在匹配这些数字的行上将 1.0 更改为 2.0(可能不是其他数字)”...不,我想将字符串s17 line linewidth 1.0 更改为s17 line linewidth 2.0s18 line linewidth 1.0 s18 line linewidth 2.0 等等,如上所示。出现在字符串s 右侧的整数从17 变为28s17, s18, s19 ... s28
  • 是的,但您不会将行的s## 部分更改为1.02.0,不是吗?因此,您的匹配等的其余部分并没有做太多,除非有 other 行具有 s## 值,而您 不想 想要更改 1.0 .

标签: python bash variables for-loop sed


【解决方案1】:

用你的数字做一个正则表达式:

allnr=""
for nr in {17..28}
do
    allnr+="${nr}|"
done
# Debug: echo "allnr=${allnr%|}"
sed -r 's/s('"${allnr%|}"') line linewidth 1\.0/s\1 line linewidth 2.0/g' ./band-structure-calcite.agr

【讨论】:

  • 感谢您的回答:)
【解决方案2】:

与其多次运行sed,不如在循环中生成一个sed脚本并运行一次:

for n in {17..28} ; do
    echo "s/s$n line linewidth 1\.0/s$n line linewidth 2.0/g"
done | sed -f- ./band-structure-calcite.agr > changed.txt

【讨论】:

  • 非常感谢,它奏效了,但我需要理解代码...行:echo "s/s$n line linewidth 1\.0/s$n line linewidth 2.0/g" 打印:s/s17 line linewidth 1\.0/s17 line linewidth 2\.0/gs/s18 line linewidth 1\.0/s18 line linewidth 2\.0/g... 然后你用 done 完成循环,然后是 | sed -f- filename 。现在,| sed -f- filename 是什么意思?再次感谢:)
  • @DavidC.:它调用 sed 将循环的输出解释为它的脚本。
【解决方案3】:

在 sed 命令的地址部分用正则表达式替换循环:

'/^s\(\(1[7-9]\)\|\(2[0-8]\)\)\s/ s/1\.0$/2.0/' ./band-structure-calcite.agr

正则表达式 (/^s\(\(1[7-9]\)\|\(2[0-8]\)\)\s/) 匹配以 s17、s18、... 或 s28 开头的行,后跟空格或制表符,sed 仅将以下 s/1\.0$/2.0/ 命令应用于这些行。其他线路不变通过。整个文件只被读取一次,并且输出包含每个输入行一个输出行,与您的原始文件不同。

【讨论】:

  • 感谢您的回答! +1!
猜你喜欢
  • 1970-01-01
  • 2016-10-23
  • 1970-01-01
  • 2016-07-07
  • 2015-01-26
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多