从工作流(文件)中删除所有非 ascii 字符

Miz*_* Ni 15 text-processing ascii

如何从一个文件中删除所有非 ascii 字符?是否有特定的命令来执行此操作?

grep --colour='auto' -P -n'[^\x00-\x7]' /usr/local/...
Run Code Online (Sandbox Code Playgroud)

我相信这会在工作流程中找到字符,但是我将如何删除相关字符的所有实例?

Kus*_*nda 32

ASCII 字符是0 到 177(八进制)范围内的字符

要删除文件中此范围之外的字符,请使用

LC_ALL=C tr -dc '\0-\177' <file >newfile
Run Code Online (Sandbox Code Playgroud)

tr命令是一个适用于单个字符的实用程序,可以将它们替换为其他单个字符(音译)、删除它们,或者将同一字符的运行压缩为单个字符。

上面的命令将读取file修改后的内容并将其写入newfile. 该-d选项tr品牌(而不是他们音译)实用程序删除字符,-c使得它考虑给定的时间间隔(内代替)之外的字符。

LC_ALL=C确保每个字节值都构成一个有效字符。没有它,tr如果某些实现在语言环境的字符编码中发现不构成有效字符的字节序列,它们就会中止。


要用修改后的文件替换原始文件,请使用

LC_ALL=C tr -dc '\0-\177' <file >newfile &&
mv newfile file
Run Code Online (Sandbox Code Playgroud)

tr成功完成后,这会将新文件重命名为旧文件的名称。如果tr没有成功完成,或者因为它无法读取原始文件或没有写入新文件,原始文件将保持不变。

或者,要尽可能多地保留原始文件的元数据(权限等),请使用

cp file tmpfile &&
LC_ALL=C tr -dc '\0-\177' <tmpfile >file &&
rm tmpfile
Run Code Online (Sandbox Code Playgroud)


小智 16

perl

perl -pi -e 's/[^[:ascii:]]//g'
Run Code Online (Sandbox Code Playgroud)


ImH*_*ere 9

如果您只需要一个正则表达式:[\x00-\x7F].
您可以应用于多个实用程序:

<file LC_ALL=C   sed   's/[^\o0-\o177]//g'      # GNU sed not POSIXLY_CORRECT
<file LC_ALL=C   awk   '{gsub(/[^\0-\177]/,"");print}'
<file            perl  -pe 's/[^[:ascii:]]//g;'
<file            tr    -dc '\0-\177'
Run Code Online (Sandbox Code Playgroud)

理解 sed、awk 和 perl 期望在 Unix 中定义“文本文件”。在这种情况下,一切都很好。但具体来说,awk 添加了一个尾随的新行(无论它是否存在于源文件中)(用 printf 替换 print 可以删除输入中的所有换行符)。在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            tr    -dc '\7-\15\40-\176'
Run Code Online (Sandbox Code Playgroud)

范围 7-13(十进制)是\a\b\t\n\v\f\r(按顺序)。
一个类似的(可能更便携)范围可以写成[^[:space:][:print:]] (similar because it doesn't include \a\b` --bell 和 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            tr     -dc '[:space:][:print:]'
Run Code Online (Sandbox Code Playgroud)

相关:正则
表达式任何 ASCII 字符
Perl 解决方案
Posix 文本文件