使用 sed 时转义“./”
Posted
技术标签:
【中文标题】使用 sed 时转义“./”【英文标题】:Escape "./" when using sed 【发布时间】:2021-12-10 14:06:55 【问题描述】:我想使用 grep 通过管道从 $lastblock 中排除单词,但我发现 grep 仅适用于文件,不适用于 stdout 输出。
所以,这就是我正在使用的:
lastblock="./2.json"
echo $lastblock | sed '1,/firstmatch/d;/.json/,$d'
我想排除 ./
和 .json
,只保留两者之间的内容。
此 sed 命令对于此目的是正确的,但是如何转义 ./
替换 firstmatch
以便它可以工作?
提前致谢!
【问题讨论】:
【参考方案1】:使用 bash 的Parameter Substitution
lastblock="./2.json"
name="$lastblock##*/" # strips from the beginning until last / -> 2.json
base="$name%.*" # strips from the last . to the end -> 2
【讨论】:
从技术上讲,P.E. 不仅仅是 bash,它也是 POSIX 定义/要求的。【参考方案2】:但我发现 grep 仅适用于文件,不适用于标准输出。
在这里。 (如果您的 grep 支持 -P
标志。
lastblock="./2.json"
echo "$lastblock" | grep -Po '(?<=\./).*(?=\.)'
但是如何逃避./
对于sed
(1),使用反斜杠\
对其进行转义
lastblock="./2.json"
echo "$lastblock" | sed 's/^\.\///;s/\..*$//'
或者使用不同的分隔符,比如管道|
sed 's|^\./||;s|\..*$||'
awk
lastblock="./2.json"
echo "$lastblock" | awk -F'[./]+' 'print $2'
从bashv3
开始,正则表达式模式匹配支持使用[[ ... ]]
关键字内的=~
运算符。
lastblock="./2.json"
regex='^\./([[:digit:]]+)\.json'
[[ $lastblock =~ $regex ]] && echo "$BASH_REMATCH[1]"
虽然 P.E. 应该足以满足此目的。
【讨论】:
【参考方案3】:我想使用 grep 通过管道从 $lastblock 中排除单词,但我发现 grep 仅适用于文件,不适用于 stdout 输出。
废话。 grep 对同一个输入的作用相同,无论是来自文件还是来自标准输入。
所以,这就是我正在使用的:
lastblock="./2.json" echo $lastblock | sed '1,/firstmatch/d;/.json/,$d'
我想排除 ./ 和 .json,只保留两者之间的内容。这个 sed 命令对于这个目的是正确的,
对于所述目的,该 sed 命令远非正确。它有这样的效果:
删除从第一行到下一个匹配正则表达式/firstmatch/
的每一行,AND
删除从第一个匹配正则表达式/.json/
到最后一个文件的每一行(注意.
是一个正则表达式元字符)。
要删除部分行而不是删除整行,请使用s///
命令而不是d
命令。至于转义,您可以通过在字符前面加上反斜杠 (\
) 将字符转义为 sed,它本身必须被引用或转义以保护它不被 shell 解释。此外,大多数正则表达式元字符在出现在字符类中时都会失去其特殊意义,我发现这是将它们作为文字包含在模式中的一种更清晰的方式。例如:
lastblock="./2.json"
echo "$lastblock" | sed 's/^[.]\///; s/[.]json$//'
也就是说要删除出现在(任何)行开头的文字字符./
,并分别删除出现在行尾的文字字符.json
。
或者,如果您只想修改都以./
开头并以.json
结尾的行,那么您可以使用带有捕获组和反向引用的单个s
命令:
lastblock="./2.json"
echo "$lastblock" | sed 's/^[.]\/\(.*\)[.]json$/\1/'
也就是说,在以./
开头并以.json
结尾的行上,捕获这两者之间的所有内容,并将整行替换为仅捕获的部分。
【讨论】:
【参考方案4】:当您想避免使用斜线时,可以使用其他字符,例如“#”。
您可以记住匹配的部分并在替换中使用它。
使用[.]
避免点为任何字符。
echo "$lastblock" | sed -r 's#[.]/(.*)[.]json#\1#'
【讨论】:
【参考方案5】:解决方案!
感谢this legendary, unrelated answer,今天才发现tr
命令。
在 Google 上搜索如何排除“.”时和“/”,100% 的 *** 答案都没有帮助。
因此,要从命令输出中转义字符,只需附加此管道:
| tr -d "character-emoji-anything-you-want-to-exclude"
所以,一个完整且简单的示例:
echo "./2.json" | tr -d "/" | tr -d "." | tr -d "json"
完成了!
【讨论】:
非常感谢@sorpigal以上是关于使用 sed 时转义“./”的主要内容,如果未能解决你的问题,请参考以下文章