bash - 删除所有Unicode空格并替换为Normal Space

Kuz*_*eko 6 unicode bash spaces sed

我有一个包含大量文本的文件,并且混合了特殊的空格字符,那些是Unicode空格

我需要用普通的 "空格"字符替换所有这些字符.

jm6*_*666 6

易于使用perl:

perl -CSDA -plE 's/\s/ /g' file
Run Code Online (Sandbox Code Playgroud)

但正如@ mklement0 corectly在评论中所说,它也将匹配\t(TAB).如果这是问题,你可以使用

perl -CSDA -plE 's/[^\S\t]/ /g'
Run Code Online (Sandbox Code Playgroud)

演示:

X?????????????X
Run Code Online (Sandbox Code Playgroud)

以上包含:

U+00058 X LATIN CAPITAL LETTER X
U+01680 ? OGHAM SPACE MARK
U+02002 ? EN SPACE
U+02003 ? EM SPACE
U+02004 ? THREE-PER-EM SPACE
U+02005 ? FOUR-PER-EM SPACE
U+02006 ? SIX-PER-EM SPACE
U+02007 ? FIGURE SPACE
U+02008 ? PUNCTUATION SPACE
U+02009 ? THIN SPACE
U+0200A ? HAIR SPACE
U+0202F ? NARROW NO-BREAK SPACE
U+0205F ? MEDIUM MATHEMATICAL SPACE
U+03000 ? IDEOGRAPHIC SPACE
U+00058 X LATIN CAPITAL LETTER X
Run Code Online (Sandbox Code Playgroud)

使用:

perl -CSDA -plE 's/\s/_/g'  <<<"X?????????????X"
Run Code Online (Sandbox Code Playgroud)

注意,对于替换为下划线的演示,打印

X_____________X
Run Code Online (Sandbox Code Playgroud)

也可以使用纯粹的bash

LC_ALL=en_US.UTF-8 spaces=$(printf "%b" "\U00A0\U1680\U180E\U2000\U2001\U2002\U2003\U2004\U2005\U2006\U2007\U2008\U2009\U200A\U200B\U202F\U205F\U3000\UFEFF")

while read -r line; do
    echo "${line//[$spaces]/ }"
done
Run Code Online (Sandbox Code Playgroud)

LC_ALL=en_US.UTF-8仅需如果默认语言环境是不是UTF-8.(你应该有,如果你使用utf8文本):)演示:

str="X?????????????X"
echo "${str//[$spaces]/_}"
Run Code Online (Sandbox Code Playgroud)

再次打印:

X_____________X
Run Code Online (Sandbox Code Playgroud)

使用相同sed- $spaces如上所述准备变量并使用:

sed "s/[$spaces]/ /g" file
Run Code Online (Sandbox Code Playgroud)

编辑 - 因为一些奇怪的复制/粘贴(或Locale)问题:

xxd -ps <<<"$spaces"
Run Code Online (Sandbox Code Playgroud)

节目

c2a0e19a80e1a08ee28080e28081e28082e28083e28084e28085e28086e2
8087e28088e28089e2808ae2808be280afe2819fe38080efbbbf0a
Run Code Online (Sandbox Code Playgroud)

md5摘要(两个不同的程序)

md5sum <<<"$spaces"
LC_ALL=C md5 <<<"$spaces"
Run Code Online (Sandbox Code Playgroud)

打印相同 md5

35cf5e1d7a5f512031d18f3d2ec6612f  -
35cf5e1d7a5f512031d18f3d2ec6612f
Run Code Online (Sandbox Code Playgroud)

  • 做得很好; 值得注意的是:使用 `\U...` 转义需要 Bash 4.x;re `perl` 解决方案:`\s` 也将匹配 _tabs_,并且可能不需要将它们替换为单个空格。一个狡辩:`printf "%b" '...'` 可以只是 `printf '...'` - 不需要 `%b` 绕道。 (2认同)
  • @ mklement0是的,我忘记了`\ t`.关于`%b` - 也是如此,但我个人喜欢显式格式.;)Thanx的评论.添加关于`\ t`的编辑. (2认同)