如何删除非ASCII http://en.wikipedia.org/wiki/ASCII文件中的字符?
如果你想使用 Perl,请这样做:
perl -pi -e 's/[^[:ascii:]]//g' filename
详细说明
以下解释涵盖了上述命令的每个部分,假设读者不熟悉解决方案中的任何内容......
-
perl
运行 perl 解释器。 Perl 是一种编程语言,通常可在所有类 UNIX 系统上使用。该命令需要在 shell 提示符下运行。
-
-p
The -p
flag 告诉 perl 迭代输入文件中的每一行,在每一行上运行指定的命令(稍后描述),然后打印结果。它相当于将你的perl程序包装在while(<>) { /* program... */; } continue { print; }
。有一个类似的-n
具有相同功能但省略的标志continue { print; }
块,所以如果你想自己打印,你可以使用它。
-
-i
The -i
flag 告诉 perl 输入文件将被就地编辑并且输出应该返回到该文件中。这对于实际修改文件很重要。省略此标志会将输出写入STDOUT
然后您可以将其重定向到一个新文件。
Note你不能省略-i
并重定向STDOUT
到输入文件,因为这会在读取输入文件之前破坏它。这只是 shell 的工作方式,与 perl 无关。这-i
flag 巧妙地解决了这个问题。
Perl 和 shell 允许您将多个单字符参数组合成一个,这就是我们可以使用的原因-pi
代替-p -i
The -i
flag 接受一个参数,这是一个文件扩展名,如果你想备份原始文件,那么如果你使用-i.bak
,然后 perl 会将输入文件复制到filename.bak
在进行更改之前。在此示例中,我省略了创建备份,因为我希望您无论如何都会使用版本控制:)
-
-e
The -e
flag 告诉 perl 下一个参数是封装在字符串中的完整 perl 程序。如果您有一个很长的程序,这并不总是一个好主意,因为这可能会变得不可读,但对于我们这里的单个命令程序,其简洁性可以提高易读性。
Note我们无法将-e
标志与-i
flag 因为它们都接受一个参数,perl 会假设第二个标志是参数,所以,例如,如果我们使用-ie <program> <filename>
,perl 会假设<program>
and <filename>
都是输入文件并尝试创建<program>e
and <filename>e
假如说e
是您要用于备份的扩展名。这将失败,因为<program>
并不是真正的文件。另一种方式 (-ei
) 也不会工作,因为 perl 会尝试执行i
作为一个程序,这会编译失败。
-
s/.../.../
这是 Perl 的基于正则表达式的替换运算符。它有四个参数。第一个位于运算符之前,如果未指定,则使用默认值$_
。第二个和第三个之间/
符号。第四场是决赛之后/
and is g
在这种情况下。
$_
在我们的代码中,第一个参数是$_
这是 perl 中默认的循环变量。如上所述,-p
flag 将我们的程序包装在while(<>)
,这会创建一个while
一次读取一行的循环(<>
)来自输入。它隐式地将这一行分配给$_
,如果未指定,所有接受单个参数的命令都将使用它(例如:仅调用print;
实际上会翻译成print $_;
)。所以,在我们的代码中,s/.../.../
运算符对输入文件的每一行运行一次。
[^[:ascii:]]
第二个参数是要在输入字符串中搜索的模式。该模式是一个正则表达式,因此包含在其中的任何内容[]
是一个括号表达式。这一部分可能是这个例子中最复杂的部分,所以我们将在最后详细讨论它。
<empty string>
第三个参数是替换字符串,在我们的例子中是空字符串,因为我们要删除所有非 ASCII 字符。
g
第四个参数是替换运算符的修饰符标志。这g
flag 指定替换应该在输入中的所有匹配项中是全局的。如果没有此标志,则仅替换第一个实例。其他可能的标志是i
对于不区分大小写的匹配,s
and m
仅与多行字符串相关(我们这里有单行字符串),o
它指定应该预编译该模式(这对于长文件可能很有用),并且x
它指定该模式可以包含空格和注释以使其更具可读性(但如果是这种情况,我们不应该将程序写在一行上)。
-
filename
这是包含我们要删除的非 ASCII 字符的输入文件。
[^[:ascii:]]
那么现在我们来讨论一下[^[:ascii:]]
更详细地说。
正如刚才提到的,[]
在正则表达式中指定一个括号表达式,它告诉正则表达式引擎匹配输入中与表达式内字符集中的任何一个字符相匹配的单个字符。所以,举例来说,[abc]
将匹配a
, or a b
or a c
,并且它将仅匹配单个字符。使用^
由于第一个字符反转匹配,所以[^abc]
将匹配任何一个不是a
, b
, or c
.
但是关于[:ascii:]
括号表达式内?
如果您有可用的基于 UNIX 的系统,请运行man 7 re_format
在命令行中阅读手册页。如果不,
[:ascii:]
是一个字符类,代表整个集合ascii
字符,但这种字符类只能在括号表达式内使用。正确的使用方法是[[:ascii:]]
并且它可能会被否定abc
上面的情况或与其他字符组合在括号表达式中,因此,例如,[éç[:ascii:]]
将匹配所有 ASCII 字符,并且é
and ç
这不是 ASCII 码,并且[^éç[:ascii:]]
将匹配所有非 ASCII 字符,也不是é
or ç
.
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)