由于更多匹配,bash没有替换匹配字符串上的一行

Posted

技术标签:

【中文标题】由于更多匹配,bash没有替换匹配字符串上的一行【英文标题】:bash not replacing a line on matching string due to more match 【发布时间】:2022-01-17 13:39:09 【问题描述】:

这可能看起来很简单,但我无法让它工作。我有一个属性文件,包含如下内容。

AVAIL_COLS=col1,col2,col3,col4,col5
SC_AVAIL_COLS=col1,col2,col3

在我的 bash 脚本中,我对可用的 cols 属性进行了一些处理和修改,并尝试在文件中替换它。如下所示。

propfile=<my property file>
line_avail_cols="AVAIL_COLS="
line_sc_avail_cols="SC_AVAIL_COLS="
available_cols=$(grep $line_avail_cols $propfile | grep -v $line_sc_avail_cols)

# Doing some operations to add few more values to same row.
available_cols="$available_cols,col6,col7,col8"

#Replace the line with new content
sed -i '/'"$line_avail_cols"'/c\'"$available_cols" $propfile

如果我的属性文件只有 AVAIL_COLS 属性而没有 SC_AVAIL_COLS,则上述脚本可以正常工作。 但是如果属性文件包含 SC_AVAIL_COLS 属性,那么它不会替换该行,而是在文件中添加一个新行,从而在文件中创建重复条目。

如何直接替换 AVAIL_COLS 属性行?文件中的行号或属性顺序可能会有所不同。所以我一直在寻找一种通用的方法。

预期输出

AVAIL_COLS=col1,col2,col3,col4,col5,col6,col7,col8
SC_AVAIL_COLS=col1,col2,col3

【问题讨论】:

你的 grep 管道在我看来很奇怪。你感兴趣的整条线是什么样子的?一个grep "^ *$line_avail_cols" "$propfile" 不够吗?或者可能是grep -wF "$line_avail_cols" "$propfile" 或者,您可以将awk 视为解决方案,即awk -F = '"AVAIL_COLS" print($0 ",col6,col7,col8") ' "$profile" &gt; "new.$propfile" 之类的东西,从而替换grepsed @user1934428 最初我只做$(grep $line_avail_cols $propfile) 并且由于相同的匹配而得到了两条线。谷歌给了我这个命令:D 脚本人不多 这当然行不通。您忘记了 ^-w(取决于您的偏好)。请参阅我在评论中给出的建议。 @user1934428 grep 无论如何都对我有用。从这个答案得到***.com/a/6064412/2353403 【参考方案1】:

您需要区分这两行,因为第二行也符合您的条件。

尝试在行首包含^,如下所示:

sed -i '/^'"$line_avail_cols"'/c\'"$available_cols" $propfile

【讨论】:

【参考方案2】:

你可以像这样修复你的脚本:

propfile="$1"
line_avail_cols="AVAIL_COLS="
line_sc_avail_cols="SC_AVAIL_COLS="
available_cols="$(grep "^$line_avail_cols" $propfile)"

# Doing some operations to add few more values to same row.
available_cols="$available_cols,col6,col7,col8"

#Replace the line with new content
sed -i "s/^$line_avail_cols.*/$available_cols/" "$propfile"

然而,所有这些都可以在一个 awk 命令中完成,也像这样:

awk -v val=',col6,col7,col8' -F= '$1 == "AVAIL_COLS" 
$0 = $0 val 1' file

AVAIL_COLS=col1,col2,col3,col4,col5,col6,col7,col8
SC_AVAIL_COLS=col1,col2,col3

【讨论】:

工作。没有尝试 awk,因为我不想修改其他行。【参考方案3】:

您可以将sed 命令更改为以下内容,以仅匹配单行。

available_cols=",col6,col7,col8"
$ sed -i.bak "/^$line_avail_cols/s/$/$available_cols/" $propfile
AVAIL_COLS=col1,col2,col3,col4,col5,col6,col7,col8
SC_AVAIL_COLS=col1,col2,col3

【讨论】:

以上是关于由于更多匹配,bash没有替换匹配字符串上的一行的主要内容,如果未能解决你的问题,请参考以下文章

用同一行开头的匹配替换一行上的所有斜杠

如果前几行匹配,则替换一行

在bash中匹配单词后的一行中打印特定字符串[重复]

正则表达式:匹配模式后跟一个空格但不匹配2个或更多空格或EOF

sed匹配全行,行首,行尾后替换或添加字符

sed命令,搜索某个字符串,结果有多个匹配行,在第一个匹配行的前面添加一行内容