匹配字符串,即使它们在SED中以空格开头

匹配字符串,即使它们在SED中以空格开头,sed,spaces,substitution,Sed,Spaces,Substitution,我在匹配字符串时遇到问题,即使它们以任意数量的空格开头。自从我开始使用正则表达式以来,时间不多了,所以我需要一些帮助 这里有一个例子。我有一个包含两行的文件(file.txt) #String1='Test One' String1='Test Two' 我试图改变第二行的值,但不影响第1行,所以我使用了这个 sed -i "s|String1=.*$|String1='Test Three'|g" 这将更改两行的值。如何使sed仅更改第二个字符串的值 谢谢使用awk您可以: awk '/S

我在匹配字符串时遇到问题,即使它们以任意数量的空格开头。自从我开始使用正则表达式以来,时间不多了,所以我需要一些帮助

这里有一个例子。我有一个包含两行的文件(file.txt)

#String1='Test One'
String1='Test Two'
我试图改变第二行的值,但不影响第1行,所以我使用了这个

sed -i "s|String1=.*$|String1='Test Three'|g"
这将更改两行的值。如何使sed仅更改第二个字符串的值


谢谢

使用
awk
您可以:

awk '/String1/ && f++ {$2="Test Three"}1' FS=\' OFS=\' file
#String1='Test One'
String1='Test Three'
它将忽略
string1
的第一次点击,因为
f
不正确。

使用GNU时,请尝试:

sed -i "s|^\s*String1=.*$|String1='Test Three'|" file


有几个解决方案可以用来解决你的问题

如果要忽略以注释字符(如“#”)开头的行,可以使用以下内容:

sed -i "/^\s*#/! s|String1=.*$|String1='Test Three'|g" file.txt
它将只在与正则表达式不匹配的行上运行以可选whiltespace
\s*
开头,后跟一个octothorp

另一个选项是将“String”前面的字符作为替换的一部分。这样做意味着您需要捕获
\(…\)
组以将其包含在
\1

sed -i "s|^\(\s*\)String1=.*$|\1String1='Test Four'|g" file.txt

使用gnu sed,您可以使用
\s
匹配空格,而其他sed实现通常使用
[:space:]
字符类。因此,选择其中一个:

sed 's/^\s*AWord/AnotherWord/'
sed 's/^[[:space:]]*AWord/AnotherWord/'
由于您使用的是
-i
,因此我假定GNU已使用。无论哪种方式,你都不应该重新键入你的单词,因为这会导致拼写错误。我同意:

sed -i "s/^\(\s*String1=\).*/\1'New Value'/" file

如果不想保留前导空格,请将
\s*
移到括号外。

问题是不要更改注释字符串的值,而此处的第二个选项将更改两个值(尽管保留注释字符不变)。在这两种情况下,由于您要匹配整行,因此在末尾包含
\g
修饰符没有多大意义;整条线路上只有一个实例。;)我提供的两个选项都经过了OP示例的测试,都没有替换注释行中的文本。这是因为两者都锚定到该线的起点。我把
|g
修饰符留在那里,因为OP有它,我认为他有它在那里的原因;第二个答案很好。那就别管了。:)如果RHS包含
=
字符,则第二个选项将无法按预期工作。然而,第一个问题是,90%以上使用sed的人都会同意,所以这可能是他想要的答案。谢谢@dannysauer!我改进了第二个选项,使RHS可以包含
=
字符。如果有人给一个减号,最好知道原因,这样我可以从中学习。可能是因为问题被标记为
sed
,而不是
awk
。使用要求之外的其他语言/技术提供解决方案通常会赢得否决票。我并不是说这是对的,我只是说,有人观察到,这个答案实际上取代了String1的第二个(以及任何后续)实例,而不是跳过注释版本。它不要求String1在LHS上,也不要求String1只是String1,因此它将匹配“String10='pie'”和“cows='NotString1'”之类的内容。我个人倾向于使用
=
作为记录分隔符,并将$1与/^[:space:]*String1$/进行匹配。我不应该在sed中使用g标志吗?
g
标志表示您希望在一行中匹配模式的所有实例。您的模式与整行匹配,因此该行上只能有零个或一个模式实例。因此,在这种情况下,
g
标志是不相关的。您认为需要匹配多行,而sed已经这样做了,除非您通过指定行选择器/范围选择器或类似的方式来限制它。
sed -i "s/^\(\s*String1=\).*/\1'New Value'/" file