如何在 bash 中的任意数量的空格之后搜索和替换字符串?
Posted
技术标签:
【中文标题】如何在 bash 中的任意数量的空格之后搜索和替换字符串?【英文标题】:How do I search and replace a string after an arbitrary amount of white space in bash? 【发布时间】:2022-01-08 10:31:10 【问题描述】:我正在使用 bash shell。我有一个仅包含该行的文本文件
name "Test Program"
我想在名称后面的字符串周围添加花括号,使文件看起来像
name “Test Program"
我尝试了下面的表达式
perl -pi -e 's/name(\s+)"(.*)"/name$1 "$2" /g' /tmp/test.txt
但最终得到的文件只包含
name
我对任意空白 (\s) 或替换是否有误解?
【问题讨论】:
sed 's/".*"/ & /' file
?
我认为“
应该是"
。
转义 perl 命令中的大括号:perl -pi -e 's/name(\s+)"(.*)"/name$1\ "$2" \/g' /tmp/test.txt
@Dave:任意空格是什么意思?在 Perl 正则表达式中,\s
表示单个空格字符(空格、制表符或换行符)。
【参考方案1】:
perl -pi -e 's/name(\s+)"(.*)"/name$1 "$2" /g' /tmp/test.txt
这里,$1 "$2"
被解释为“%1
哈希的$2
键”。
在$1
变量周围加上大括号以消除扩展的歧义:
perl -pi -e 's/name(\s+)"(.*)"/name$1 "$2" /g' /tmp/test.txt
# ..................................^.^
或转义左大括号
perl -pi -e 's/name(\s+)"(.*)"/name$1\ "$2" /g' /tmp/test.txt
# ...................................^
或者,使用\K
运算符
perl -pi e 's/name\s+\K(".*")/ $1 /' test.txt
【讨论】:
【参考方案2】:假设只有一对双引号,并且不限于perl
解决方案...
一个想法使用sed
:
sed -E 's/("[^"]*")/ \1 /' test.txt
地点:
-E
- 启用扩展正则表达式(和捕获组)
("[^"]*")
- (捕获组)匹配 "
+ 0 个或多个 non-"
字符 + "
\1
- 将匹配替换为
+ 捕获组 +
这会生成:
name "Test Program"
一旦结果正确,您可以添加-i
标志以对源文件进行更改,例如:
$ cat test.txt
name "Test Program"
$ sed -Ei 's/("[^"]*")/ \1 /' test.txt
$ cat test.txt
name "Test Program"
假设我们需要验证 name
字符串的匹配...
sed -E 's/([[:space:]]*name[[:space:]]+)("[^"]*")/\1 \2 /' test.txt
地点:
([[:space:]]*name[[:space:]]+)
-(第一个捕获组)是 0 个或多个空格 + name
+ 1 个或多个空格
("[^"]*")
- (第二个捕获组)解释和以前一样
\1 \2
- 第一个捕获组 +
+ 第二个捕获组 +
示例数据文件:
$ cat test.txt
name "Test Program"
name "Test Program"
boat "Test Program"
names "Test Program"
$ sed -E 's/([[:space:]]*name[[:space:]]+)("[^"]*")/\1 \2 /' test.txt
name "Test Program"
name "Test Program"
boat "Test Program"
names "Test Program"
【讨论】:
谢谢!关于 'sed -E 's/([[:space:]]*name[[:space:]]+)("[^"]*")/\1 \2 /'test.txt',有什么方法可以修改它以使编辑到位?现在它正在将结果输出到屏幕上。最终我想将一堆文件传递给命令并让它们在每个文件上运行。 @Dave 是的,您可以对文件进行编辑...如前所述,添加-i
标志(参见示例 - 上面 - sed -Ei ...
)【参考方案3】:
尝试使用 sed:
cat test.txt | sed 's/^name[ ]\+/name /g' | sed 's/["][ ]*$/" /g'
【讨论】:
这会在屏幕上输出 'name "Test Program" ',但我想要 'name "Test Program" '。另外,有什么方法可以直接在文件中进行更改而不将它们输出到屏幕上?【参考方案4】:你可以使用这个perl
命令:
perl -i -pe 's/(name\s+)("[^"]+")/$1 $2 /' file
cat file
name "Test Program"
或者这个sed
:
sed -i.bak -E 's/(name[[:blank:]]+)("[^"]+")/\1 \2 /' file
【讨论】:
以上是关于如何在 bash 中的任意数量的空格之后搜索和替换字符串?的主要内容,如果未能解决你的问题,请参考以下文章