如何从一个文件中删除所有非ASCII字符?是否会有特定的命令来执行此操作?
grep --colour='auto' -P -n'[^\x00-\x7]' /usr/local/...
我相信这可以在工作流程中找到字符,但是如何删除有问题的字符的所有实例?
cat -v
ASCII表示形式来显示它们。(例如,^G
用于\007
)
如何从一个文件中删除所有非ASCII字符?是否会有特定的命令来执行此操作?
grep --colour='auto' -P -n'[^\x00-\x7]' /usr/local/...
我相信这可以在工作流程中找到字符,但是如何删除有问题的字符的所有实例?
cat -v
ASCII表示形式来显示它们。(例如,^G
用于\007
)
Answers:
ASCII字符是介于0到177(八进制)之间的字符。
要删除文件中超出此范围的字符,请使用
LC_ALL=C tr -dc '\0-\177' <file >newfile
该tr
命令是一个适用于单个字符的实用程序,可以用其他单个字符替换它们(音译),删除它们或将相同字符的行程压缩为单个字符。
上面的命令将从中读取file
修改的内容并将其写入newfile
。该-d
选项tr
品牌(而不是他们音译)实用程序删除字符,-c
使得它考虑给定的时间间隔(内代替)之外的字符。
LC_ALL=C
确保每个字节值组成一个有效字符。没有它,tr
如果某些实现在语言环境的字符编码中发现未形成有效字符的字节序列,它们将中止。
要将原始文件替换为修改后的文件,请使用
LC_ALL=C tr -dc '\0-\177' <file >newfile &&
mv newfile file
tr
成功完成后,这会将新文件重命名为旧文件的名称。如果tr
由于无法读取原始文件或无法写入新文件而未能成功完成,则原始文件将保持不变。
或者,要保留尽可能多的原始文件的元数据(权限等),请使用
cp file tmpfile &&
LC_ALL=C tr -dc '\0-\177' <tmpfile >file &&
rm tmpfile
用 perl
perl -pi -e 's/[^[:ascii:]]//g'
如果您只需要一个正则表达式:[\x00-\x7F]
您可以将其应用于多个实用程序:
<file LC_ALL=C sed 's/[^\o0-\o177]//g' # GNU sed without POSIXLY_CORRECT
<file LC_ALL=C awk '{gsub(/[^\0-\177]/,"");print}'
<file perl -pe 's/[^[:ascii:]]//g;'
<file LC_ALL=C tr -dc '\0-\177'
了解sed,awk和perl期望使用Unix中定义的“文本文件”。在这种情况下,所有人都可以正常工作。但是具体来说,awk添加了结尾的换行符(无论它是否存在于源文件中)(使用printf会删除输入中的所有换行符)。tr旨在与任何文件类型一起使用。但是NUL(\0
)在POSIX文本文件中不是有效字符,应避免使用:
这些行不包含NUL字符...
实际上,许多控制字符在某些特定条件下还会产生其他问题。
所以,可能你需要[\x07-\x0d\x20-\x7e]
<file LC_ALL=C sed 's/[^\o007-\o015\o040-\o176]//g' # GNU sed without POSIXLY_CORRECT
<file LC_ALL=C awk '{gsub(/[^\0-\15\40-\176]/,"");print}'
<file perl -pe 's/[^\x{7}-\x{d}\x{20}-\x{7e}]//g;'
<file LC_ALL=C tr -dc '\7-\15\40-\176'
范围7-13(十进制)是\a\b\t\n\v\f\r
(按顺序)。
类似的(可能更便于携带)范围可以写为[^[:space:][:print:]] (similar because it doesn't include
\ a \ b` -bell and backspace--)。
<file LC_ALL=C sed 's/[^[:space:][:print:]]//g' # GNU sed without POSIXLY_CORRECT
<file LC_ALL=C awk '{gsub(/[^[:space:][:print:]]/,"");print}'
<file perl -pe 's/[^[:space:][:print:]]//g;'
<file LC_ALL=C tr -dc '[:space:][:print:]'
相关:正则
表达式任何ASCII字符
Perl解决方案
Posix文本文件
tr
可以是任何类型的文件,而不仅仅是文本文件。awk
另一方面,需要一个文本文件。
gensub()
是gawk扩展。您需要gsub(...); print
,并且使用八进制而不是十六进制序列(和LC_ALL = C)是(更多)可移植的。
[^\o0]
与POSIX中反斜杠,o和0以外的其他字符匹配sed
(在所有实现中,但GNU sed除外)。这不是GNU 的限制,sed
而是非兼容的扩展,这就是为什么当POSIXLY_CORRECT在环境中时将其禁用的原因。