问题1-2)

问题1-2)

我是编程新手(/脚本?),因为这会清楚地表明。

目的:

尝试创建一个可重用的脚本来自动安装/配置新的 linux 实例......因为我不断地破坏它们。在这种情况下,我正在摆弄 /etc/pam.d/sshd

学习... sed 确实让我了解了引号、中断和所有基础知识。

正如你所看到的,我已经让它工作了,但有几个问题(我怀疑有人会指出这种方法是多么脆弱)

问题1-2)

变量文件- 作为参数传递给 sedinsert.sh

sedfind="# Standard Un\*x authentication."
#sedfind=".* Standard Un\*x authentication"
sedinsert="I am a \nmulti line variable \nand I kind of work"
sedfile=sshd

我试图让它完成繁重的工作,即我将转义 sed 命令中所需的任何字符或在此处使用通配符,因为这样我只需在更新时更改变量文件一次,至少对我来说,这是一个干净一点。

它还极大地帮助我的理解,因为我可以轻松地看到变化如何影响输出/结果。

Q1.我在这里引用的内容和新的台词对吗?这似乎可行,但还有其他方法吗?我有一种可怕的感觉,我很快就会遇到一个会打破这个的角色 - 有例子吗?

Q2。是否可以将变量拆分为多行,以便在必要时使该文件更易于使用(例如,类似于在行末尾使用 \ ) - 记住即将出现的 source 和 sed 。
也许脚本中的另一个命令可以处理这个问题? (Grep?或另一个 sed?。

问题2

sedinsert.sh

set -x
source $1
sed -i "\|$sedfind|a\ \n$sedinsert" $sedfile

我试图尽可能保持干净,并且不要在变量周围使用引号。我目前有另一个要替换的,但接下来我可能会考虑将命令作为变量传递

我并不完全同意这个想法,但希望原因是有意义的......即这将用于更改其中包含“困难”字符的各种文件,例如@#“等

问:因此,我必须将第一个新行放在命令本身中(|a\/n....)。如果我不想要它/想要包含多个空行,是否可以通过某种方式将其放入变量本身?

问题3

在 sed 中,您可以将模式分隔符(正确的术语?)从 \ 设置为 | ,这很好。就像我在这里一样。

但每次我认为我找到了一个好用的文件时,我肯定会发现它包含在我查看的下一个文件中

问:是否有一些建议/标准的模糊分隔符在其他地方很少使用 - 所以我不会一直在文件中找到它,例如一些俄语字符(向任何俄罗斯人道歉)而不是#|等。

我只是有点困惑为什么每个人都使用常见的,这似乎导致人们在其他答案中遇到各种困惑(例如/在文件路径中)

问题 4:现在我应该如何处理这一切?

以 pam.sshd 的几行为例

# PAM configuration for the Secure Shell service

# Standard Un*x authentication.
@include common-auth

# Disallow non-root logins when /etc/nologin exists.
account    required     pam_nologin.so

抱歉太长了 - 认为值得解释整个过程

答案1

自从sedinsert.sh包含source我假设您使用 bash 的命令。

问题1-2)

Q1.

你是对的。

Q2。

实际上,可以有一个带有换行符的变量:

sedinsert="I am a 
multi line variable 
and I kind of work"

采购就可以了变量文件是一个有效的 bash 脚本。

出于您的目的,您可以使用此变量(在每个换行符前面附加反斜杠):

sedinsert="I am a \
multi line variable \
and I kind of work"

与 sed 一起使用时需要反斜杠。现在您可以使用您的命令而无需更改:

sed -i "\|$sedfind|a\ \n$sedinsert" $sedfile

问题2

sed 命令a \应该与换行符一起使用,如下所示:

sed -i "\|$sedfind|a \
$sedinsert" $sedfile

例如,命令

sed "/ping/a \
pong" -i file.txt

pong将在每个包含子字符串“ping”的字符串后面添加一个字符串(没有额外的换行符和空格)。

如果您不喜欢它的外观,可以使用$'word'机制来表示换行符:

sed "/ping/a \"$'\n'"pong" -i file.txt

或者

newline=$'\n'
sed "/ping/a \${newline}pong" -i file.txt

问题3

首先,每个符号都图案(例如 的值sedfind)不包含它。文件的内容$sedfile并不重要。分隔符仅用于指示模式结束。其次,如果需要在模式中使用分隔符,可以使用反斜杠转义所有出现的字符:

sed "\|bar\|bar| a \
foo-foo"

foo-foo在每个包含的字符串后面添加一个字符串bar|bar

是否有一些建议/标准的模糊分隔符可供使用,但在其他地方很少使用?

我对此一无所知。

顺便说一句,我的 sed 版本不接受俄语字符作为分隔符(错误消息delimiter character is not a single-byte character)。

概括

现在你可以使用这个变量文件

sedfind="# Standard Un\*x authentication."  # all occurrences of symbol '|' must be escaped by backslash as far as '|' is sed pattern delimiter
#sedfind=".* Standard Un\*x authentication"
sedinsert="I am a \
multi line variable \
and I kind of work"
sedfile=sshd

和这个sedinsert.sh

set -x
source $1
sed -i "\|$sedfind|a \
$sedinsert" $sedfile

最好用双引号将变量引起来(否则脚本将在具有特殊符号的文件名上崩溃):

set -x
source "$1"
sed -i "\|$sedfind|a \
$sedinsert" "$sedfile"

该脚本将在与模式匹配的$sedinsert每一行文件之后添加字符串。$sedfile$sedfind


关于引用、正则表达式和 sed 脚本编写的好教程,人们可能会发现它很有用:http://www.grymoire.com/Unix/

相关内容