我想删除所有特殊字符,只留下 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..txt
像tr
基于 - 的解决方案。
答案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]
使用ksh93
or 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+
,匹配一个或多个x
s。
答案4
你可以这样做tr
:
x='Some Movie Name! (2015) [1080p]'
printf '%s\n' "$x" | tr -cd 'A-Za-z0-9.()[] ' | tr ' ' '.'
Some.Movie.Name.(2015).[1080p]