如何使用sed或awk匹配和替换字符串后面的内容

3

我有一个文件,想要使用cat将其修改为一个新文件。所以文件包含如下行:

name "myName"
place "xyz" 

我希望你能将这些行改为

name "Jon"
place "paris"

我试图这样做,但它并没有起作用:
cat originalFile | sed 's/^name\*/name "Jon"/' > tempFile 

我尝试使用各种特殊字符,但没有成功。我无法识别“name”后面的空格字符以及“myName”。


名称 "myName" \n 地点 "xyz" \n 等等... - Heyya
sed 's/^name .*/name "Jon"/;s/^place .*/place "paris"/' originalFile > tempFile - Wiktor Stribiżew
@WiktorStribiżew 这个怎么样? sed -E 's/^(name).*(place).*/\1 "Jon" \2 "Paris"/g' filename,这样做不好吗? - Mostafa Hussein
为什么你没有使用分组然后用\1\2来调用它,另外我使用了扩展正则表达式但你没有。这让我想知道是否有任何重大的区别使你更喜欢以这种方式编写?我知道你是正则表达式方面的专家:D - Mostafa Hussein
1
@MostafaHussein 因为我选择了BRE。这完全是个人喜好:如果您想保留的模式部分是字面值,则不需要组/反向引用。采用KISS方法。 - Wiktor Stribiżew
显示剩余2条评论
2个回答

2

您可以使用.*匹配行的其余部分,并且可以使用空格或[[:blank:]][[:space:]]来匹配空格:

最初的回答

sed 's/^\(name[[:space:]]\).*/\1"Jon"/;s/^\(place[[:space:]]\).*/\1"paris"/' originalFile > tempFile

请注意这里有两个替换命令,用s分号连接。第一部分用一个捕获组包裹起来是必要的,因为空格POSIX字符类不是文字字符,在替换后保留它需要使用\1反向引用(插入通过组1捕获的文本)。

请参见在线演示

s='name "myName"
place "xyz"'
sed 's/^\(name[[:space:]]\).*/\1"Jon"/;s/^\(place[[:space:]]\).*/\1"paris"/' <<< "$s"

输出:

name "Jon"
place "paris"

感谢您的解决方案。我还有一个问题,如果在名称和“myName”之间有空格和制表符该怎么处理?我可能会遇到只有空格字符的情况,也可能会遇到制表符的情况,还可能同时出现两者。目前,s/^name.*/name "Jon"/' 对我有效。但我想要针对上述三种情况进行全面的处理。 - Heyya
@Heyya 你已经得到了答案:使用[[:space:]],它可以同时适用于\t或普通空格。 - Til
嗨,使用 sed 's/^\(name[[:space:]]\).*/\1"Jon"/;s/^\(place[[:space:]]\).*/\1"paris"/' originalFile > tempFile - Wiktor Stribiżew
@Heyya,这个方案对你有用吗?如果有的话,请考虑接受答案。 - Wiktor Stribiżew

0
一个 awk 的替代方案:
awk '$1=="name"{$0="name \"Jon\""} $1=="place"{$0="place \"paris\""} 1' originalFile

如果在nameplace之前有空格,它将起作用。
这里不是正则表达式匹配,而只是字符串比较。
awk通过包括\n的空格字符分隔字段。

当结果看起来正确时,请附加> tempFile


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接