如何使用 sed 将空格替换为句点并仍然保留 () 和

如何使用 sed 将空格替换为句点并仍然保留 () 和

我想删除所有特殊字符,只留下 A-Za-z0-9.()[]

echo 'Some Movie Name! (2015) [1080p]' |sed -e 's/[^A-Za-z0-9.()[]]/./g'

给我这个输出:

Some Movie Name! (2015) [1080p]

这就是我要的:

Some.Movie.Name.(2015).[1080p]

我不知道如何逃避“]”“]”不起作用。

我能得到的最接近的是:

echo 'Some Movie Name! (2015) [1080p]' |sed -e 's/[^A-Za-z0-9.()[]/./g'
Some.Movie.Name..(2015).[1080p.

然后我可以再次通过管道将其传递给 sed 以删除双句点:

|sed 's/\.\././g'

答案1

根据@Glenn Jackman 的敏锐观察,该方法更改为以下内容:

$ printf '%s\n' "$string" | tr -cs '[:alnum:].[]()\n' '[.*]'
  • -c=> 反转/求补输入集
  • -s=> 会将数据中找到的补码输入集中的连续字符压缩为单个点字符。

tr请注意,支持多字节字符的实现很少sed。特别是 GNUtr不支持,而 GNU 则sed支持,因此,例如,要使用 UTF-8 输入处理非英语字母,您可能需要切换到sed

printf '%s\n' "$string" | sed 's/[^][[:alnum:]()]\{1,\}/./g'

请注意,]必须紧接在 之后^。另请注意,我们.从补充集中删除了 ,以便foo-.txt例如将其更改为foo.txt而不是foo..txttr基于 - 的解决方案。

答案2

将您想要匹配的结束语]直接放在否定之后,^以免被误解。您可以\+在正则表达式的末尾使用一个句点替换多个字符(感谢@Rakesh Sharma):

$ echo 'Some Movie Name! (2015) [1080p]' | sed -e 's/[^][A-Za-z0-9()]\+/./g'
Some.Movie.Name.(2015).[1080p]

答案3

zsh

$ set -o extendedglob
$ string='Some Movie Name! (2015) [1080p]'
$ printf '%s\n' ${string//[^][()[:alnum:]]##/.}
Some.Movie.Name.(2015).[1080p]

使用ksh93or bash -O extglob(在shopt -s extglob不使用 bash 调用之后开始-O extglob):

$ string='Some Movie Name! (2015) [1080p]'
$ printf '%s\n' "${string//+([^][()[:alnum:]])/.}"
Some.Movie.Name.(2015).[1080p]

zshx##或 ksh+(x)类似于扩展正则表达式x+,匹配一个或多个xs。

答案4

你可以这样做tr

x='Some Movie Name! (2015) [1080p]'
printf '%s\n' "$x" | tr -cd 'A-Za-z0-9.()[] ' | tr ' ' '.'
Some.Movie.Name.(2015).[1080p]

相关内容