使用 sed 时转义“./”

Escape "./" when using sed

我想使用 grep 通过管道从 $lastblock 中排除单词,但我发现 grep 仅适用于文件,不适用于 stdout 输出。

所以,这是我正在使用的:

lastblock="./2.json"
echo $lastblock | sed '1,/firstmatch/d;/.json/,$d'

我想排除 ./.json,只保留介于两者之间的内容。 此 sed 命令对于此目的是正确的,但是如何转义 ./ 替换 firstmatch 以便它可以工作? 提前致谢!

使用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

but I found that grep works only for files, not for stdout output.

在这里。 (如果你的 grep 支持 -P 标志。

lastblock="./2.json"
echo "$lastblock" | grep -Po '(?<=\./).*(?=\.)'

but how to escape the ./

对于 sed(1),使用反斜杠将其转义 \

lastblock="./2.json"
echo "$lastblock" | sed 's/^\.\///;s/\..*$//'

或者使用不同的分隔符,例如竖线 |

sed 's|^\./||;s|\..*$||'

awk

lastblock="./2.json"
echo "$lastblock" | awk -F'[./]+' '{print }'

bashv3 开始,在 [[ ... ]] 关键字内使用 =~ 运算符支持正则表达式模式匹配。

lastblock="./2.json"
regex='^\./([[:digit:]]+)\.json'
[[ $lastblock =~ $regex ]] && echo "${BASH_REMATCH[1]}"

虽然 P.E. 应该足以满足此目的。

I wanted to use grep to exclude words from $lastblock by using a pipeline, but I found that grep works only for files, not for stdout output.

废话。 grep 对相同的输入工作相同,不管它是来自文件还是来自标准输入。

So, here is what I'm using:

lastblock="./2.json"
echo $lastblock | sed '1,/firstmatch/d;/.json/,$d'

I want to exclude ./ and .json, keeping only what is between. This sed command is correct for this purpose,

该 sed 命令与所述目的相去甚远。效果是这样的:

  • 删除每个 从第一个到并包括下一个匹配正则表达式 /firstmatch/, AND
  • 删除每个 从第一个匹配正则表达式 /.json/ 到文件的最后一个(注意 . 是一个正则表达式元字符).

要删除部分行而不是删除整行,请使用 s/// 命令而不是 d 命令。至于转义,您可以通过在字符前面加上反斜杠 (\) 来将字符转义到 sed,反斜杠本身必须被引用或转义以保护它不被 shell 解释。此外,当大多数正则表达式元字符出现在字符 class 内时,它们将失去其特殊意义,我发现将它们作为文字包含在模式中是一种更易读的方式。例如:

lastblock="./2.json"
echo "$lastblock" | sed 's/^[.]\///; s/[.]json$//'

这表示删除出现在(任何)行开头的文字字符 ./,并分别删除出现在行尾的文字字符 .json

或者,如果您只想修改 ./ 开头并以 .json 结尾的那些行,那么您可以使用单个 s 带有捕获组和反向引用的命令:

lastblock="./2.json"
echo "$lastblock" | sed 's/^[.]\/\(.*\)[.]json$//'

也就是说,在以 ./ 开头并以 .json 结尾的行上,捕获这两者之间的所有内容,并单独用捕获的部分替换整行。

如果您不想使用斜线,可以使用其他字符,例如“#”。
您可以记住一个匹配的部分并在替换中使用它。
使用 [.] 避免点是任何字符。

echo "$lastblock" | sed -r 's#[.]/(.*)[.]json##'

解决方案!

今天刚发现 tr 命令,感谢 this legendary, unrelated answer

在 Google 中搜索如何排除“.”时和“/”,100% 的 Whosebug 答案都没有帮助。

因此,要从命令的输出中转义字符,只需附加此管道:

| tr -d "{character-emoji-anything-you-want-to-exclude}"

所以,一个完整的工作和简单的示例:

echo "./2.json" | tr -d "/" | tr -d "." | tr -d "json"

大功告成!