所以我的问题很大程度上是基于相关问题,但有一个关键的区别。
在给出的答案中:
sed '/^FOOBAR=/{h;s/=.*/=newvalue/};${x;/^$/{s//FOOBAR=newvalue/;H};x}' infile
我做了一个变体,用于创建FOOBAR
变量(例如,程序的名称,然后将其放入 for 循环中以生成程序及其安装状态的列表)。这是针对我正在开展的一个相当复杂的项目,目的是使为 Raspberry Pi 安装 Drawile 并启用一些新功能,但这是另外一个棘手的问题,我不想深入探讨。
sed -i '/^'"$FOOBAR"'=/{h;s/=.*/=newvalue/};${x;/^$/{s//'"FOOBAR"'=newvalue/;H};x}' infile
我希望newvalue
成为$variable
可以在脚本中更改的。我只是不知道如何让它工作,简单地使用'
和"
做不到。我花了几个小时浏览和尝试阅读教程,但我理解得不够,并且已经深入研究了 sed 的内部工作原理。大多数情况下,这个变量会很简单,例如:yes
,no
或error
。但是,我可能还会用它来表示文件夹和文件路径……所以我也担心/
这里的替换。即使这不是一个完整的答案,只要我能找到更好地理解这一点所需的方向,我也很乐意自己弄清楚。
编辑:由于我确定我遗漏了一些基本知识,所以没有太多内容可以发布,我只是尝试了将 newvalue 括起来的各种方法。例如:
sed -i '/^FOOBAR=/{h;s/=.*/=$newvalue/};${x;/^$/{s//FOOBAR=$newvalue/;H};x}' infile
输出:FOOBAR = $newvalue
这是不正确的。应该输出存储的值newvalue
!
sed -i '/^FOOBAR=/{h;s/=.*/="$newvalue"/};${x;/^$/{s//FOOBAR="$newvalue"/;H};x}' infile
输出:FOOBAR = "$newvalue"
这是不正确的。应该输出存储的值newvalue
!
sed -i '/^FOOBAR=/{h;s/=.*/='"$newvalue"'/};${x;/^$/{s//FOOBAR='"$newvalue"'/;H};x}' infile
输出:sed: -e expression #1, char 30: unknown option to `s'
如果newvalue
等于Yes
,那么我希望输出是FOOBAR = Yes
或可能是文件夹路径。
答案1
我们来看一下 的基本形式sed
。
用法:
sed [OPTION]... {script-only-if-no-other-script} [input-file]...
这就是我得出的答案。
sed -i '\!^'"$FOOBAR"'=!{h;s!=.*!='"$newvalue"'!};${x;\!^$!{s!!'"$FOOBAR"'='"$newvalue"'!;H};x}' /home/pi/Public/test.txt
从左到右的解释:
-i
用于就地编辑文件,即无需备份即可编辑原始文件。'
用于启动我们将用来实现目标的表达式脚本。!
必须用来代替典型的/
分隔符,因为我们期望输入可能/
在文件夹或文件路径中使用。第一个感叹号被转义以确保它被正确解释- 第一部分寻找现存的复制任何内容
$FOOBAR
,例如apache2
程序安装状态。以下要点特定于我们的 sed 查询的这一部分。^
是一个正则表达式,表示它将匹配行的起始位置。这意味着它将匹配$FOOBAR
行的开头,而不是以下任何内容:$FOOBAR
、THIS IS $FOOBAR
等。'"
和"'
包围$FOOBAR
,因为它是确保脚本正确解释变量所必需的。如果没有它,它最终会打印$FOOBAR
到文档中,而不是变量包含的值$FOOBAR
。后面的等号只是我们正在寻找的预期文本部分的一部分。- 用于
{
对命令进行分组。 - 该
h
命令将模式缓冲区复制到保留缓冲区中以供稍后使用。这是一个单行缓冲区,因此它一次不能容纳多行。 - 该
;
命令用于将多个 sed 命令合并到一行中。不幸的是,它的文档似乎相当少。您可以在此处阅读更多信息http://www.grymoire.com/Unix/Sed.html#uh-61 - 表示
s
将使用新模式的一部分来替代。 .*
是一个正则表达式,在本例中,表示在新行开始之前查找等号后跟任意数量的字符。它将用等号后跟 替换它$newvalue
,例如= yes
或= no
。变量$newvalue
被 包围'"
,并且"'
出于同样的原因$FOOBAR
包含它们。然后我们输入最后一个分隔符并关闭分组命令。
- 这是 sed 命令的第二部分。以下要点特定于 sed 查询的这一部分。重复的部分将被跳过。
- 查找
$
文件最后一行的结尾。然后我们开始新的分组命令系列。 - 将
x
模式空间与保持缓冲区进行交换。这是我自己有点糊涂的部分,但在我看来,此时 sed 正在修改整个文件,如此处所述。我试图在最后一点中对此进行更多解释。在此处阅读更多内容 -http://www.grymoire.com/Unix/Sed.html#uh-53 - 这
^$
意味着我们正在寻找一个段落返回,它既是行的开始也是行的结束,并且这一行上没有任何类型的字符。 - 然后我们继续用双定界符感叹号替换该无字符行,并用变量
$FOOBAR
和替换该值$newvalue
。 - 与
H
小写字母相同,h
它是一个保留缓冲区,但用于多行。我们关闭该分组并再次用 替换它x
。这基本上是首先在文档顶部插入我们想要的行。Sed 逐行浏览文档,取出其下方的行并将其移动到我们插入的行上方。由于 sed 的工作方式类似于“管道”,是一个流编辑器,它会一直这样做,直到到达文档末尾并停止处理更改。
- 查找
- 最后是需要修改的文件:
/home/pi/Public/test.txt
。
我想我已经解释清楚了一切,欢迎反馈。