提问人:john Wallace 提问时间:1/2/2020 更新时间:1/2/2020 访问量:392
将变量与包含空格 (\s) 和 sed 的正则表达式一起使用
Using Variables with Regex that contain a space (\s) and sed
问:
我尝试使用文字字符串变量和正则表达式创建排序脚本,并在 bash 中使用 sed 创建排序脚本。使用变量时,我似乎找不到带有空格的文字字符串,尽管在直接使用正则表达式时可以找到它们。所以:
#!/bin/bash
group1="IRISHFHD"
group2="REGIONAL FHD"
sed -i '/group-title="'${group1}/',+1d' JWLINE.m3u
sed -i '/group-title="'${group2}/',+1d' JWLINE.m3u
我尝试将 \s 添加到组变量中,但它不起作用。
John
答:
2赞
Gordon Davisson
1/2/2020
#1
这个问题与正则表达式无关,这完全取决于 shell 如何处理变量的值。当一个变量被扩展而没有双引号时(即 ),shell 会根据空格将其拆分为“单词”。它还将尝试将任何包含 shell 通配符的单词扩展为匹配文件的列表,并且一些正则表达式元字符看起来像 shell 通配符,这可能会导致严重的混乱。${group2}
在此示例中:
sed -i '/group-title="'${group2}/',+1d' JWLINE.m3u
这有点复杂,因为变量引用位于两个单引号部分之间。在这种情况下,变量引用之前的部分附加到变量中的第一个“单词”,之后的部分附加到最后一个单词。从本质上讲,它扩展为以下等价物:
sed -i '/group-title="REGIONAL' 'FHD/,+1d' JWLINE.m3u
^ That's a space between arguments
无论如何,由于它在空格上被拆分,因此得到两个部分参数而不是一个完整的参数,并且它根本不起作用。sed
解决方案:与几乎所有情况一样,您应该在变量引用周围使用双引号,以防止出现这样的奇怪效果。有几个选项。你可以在变量部分周围添加双引号:
sed -i '/group-title="'"${group2}"/',+1d' JWLINE.m3u
...但 IMO 这令人困惑;其中一些引号是语法的(即由 shell 解析),一个是字面的(作为正则表达式的一部分传递给),哪些是哪个并不明显。我宁愿在整个事情周围使用双引号,并转义应该是字面意思的双引号:sed
sed -i "/group-title=\"${group2}/,+1d" JWLINE.m3u
^^ Escape makes this " a literal part of the argument.
(在双引号中,您还需要转义任何美元符号、反斜杠或反引号,这些符号本应是参数的字面部分。但在这种情况下,没有这些。
评论
1赞
Gordon Davisson
1/2/2020
的内容是什么?另外,你用的是哪个?不同的版本(例如GNU与bsd)的行为略有不同(例如,GNU版本可以识别为,但bsd版本不会;bshd需要文件扩展名参数(或没有备份),但GNU不需要;等等)。另外,试着把这个麻烦的命令放在前面(在它后面加上'set +x),shell会打印出相当于扩展后的命令,这可能会澄清发生了什么。JWLINE.m3u
sed
\s
[[:space:]]
-i
''
set -x
0赞
john Wallace
1/2/2020
对不起,戈登,我的错。事实上,您的建议非常有效。感谢您的帮助。
1赞
Paul Hodges
1/2/2020
顺便说一句,这不能在一次执行中完成吗?sed -i "/group-title=\"${group1}/,+1d; /group-title=\"${group2}/,+1d" JWLINE.m3u
评论
sed -i '/group-title="'"$group2"'/,+1d' JWLINE.m3u