Unix 删除文件中的非ASCII字符

Unix 删除文件中的非ASCII字符,unix,Unix,如何从文件中删除非字符?tr-dc[:graph:][:cntrl:][input file>cleaned文件 tr -dc [:graph:][:cntrl:] < input-file > cleaned-file 假设您希望保留“控制”字符和“可打印”字符。按要求拉小提琴。我的:这可能解决不了你的问题,但可能会给你一些提示 该命令告诉您文件编码,即ASCII等,并且iconv可以在不同编码之间转换文件。perl-pe的//[[:^ASCII:][/g'output.txt

如何从文件中删除非字符?

tr-dc[:graph:][:cntrl:][input file>cleaned文件
tr -dc [:graph:][:cntrl:] < input-file > cleaned-file
假设您希望保留“控制”字符和“可打印”字符。按要求拉小提琴。

我的:这可能解决不了你的问题,但可能会给你一些提示

该命令告诉您文件编码,即ASCII等,并且
iconv
可以在不同编码之间转换文件。

perl-pe的//[[:^ASCII:][/g'output.txt
perl -pe's/[[:^ascii:]]//g' < input.txt > output.txt

如果要使用Perl,请按如下方式操作:

perl -pi -e 's/[^[:ascii:]]//g' filename
#include <stdio.h>
#include <ctype.h>

int main(int argc, char **argv)
{
   FILE *fin = fopen("source_file", "rb");
   FILE *fout = fopen("target_file", "w");
   int c;
   while ((c = fgetc(fin)) != EOF) {
       if (isprint(c))
          fputc(c, fout);
   }
   fclose(fin);
   fclose(fout);
   return 0;
}
详细说明

假设读者不熟悉解决方案中的任何内容,下面的解释涵盖了上述命令的每一部分

  • perl

    运行perl解释器。Perl是一种编程语言,通常可用于所有类unix系统。此命令需要在shell提示符下运行

  • -p

    -p
    标志告诉perl迭代输入文件中的每一行,在每一行上运行指定的命令(稍后描述),然后打印结果。这相当于在
    中包装perl程序,而(){/*程序…*/;}继续{print;}
    。有一个类似的
    -n
    标志,它的作用相同,但省略了
    继续{print;}
    块,因此如果您想自己进行打印,可以使用它

  • -i

    -i
    标志告诉perl输入文件要就地编辑,输出应该返回到该文件中。这对于实际修改文件很重要。省略此标志将把输出写入
    STDOUT
    ,然后可以重定向到新文件

    注意不能省略
    -i
    并将
    STDOUT
    重定向到输入文件,因为这将在读取输入文件之前对其进行破坏。这就是shell的工作方式,与perl无关。
    -i
    标志智能地解决了这一问题

    Perl和shell允许您将多个单字符参数组合成一个参数,这就是为什么我们可以使用
    -pi
    而不是
    -p-i

    -i
    标志使用一个参数,如果要备份原始文件,则使用该参数作为文件扩展名,因此如果使用
    -i.bak
    ,则perl将在进行更改之前将输入文件复制到
    filename.bak
    。在本例中,我省略了创建备份,因为我希望您仍将使用版本控制:)

  • -e

    -e
    标志告诉perl下一个参数是封装在字符串中的完整perl程序。如果你有一个很长的程序,这并不总是一个好主意,因为它可能会变得不可读,但是对于我们这里的单个命令程序,它的简洁性可以提高可读性

    注意我们不能将
    -e
    标志与
    -i
    标志组合在一起,因为它们都接受一个参数,perl会假定第二个标志是参数,因此,例如,如果我们使用
    -ie
    ,perl将假定
    都是输入文件,并尝试创建
    e
    e
    ,假定
    e
    是要用于备份的扩展名。这将失败,因为
    不是真正的文件。另一种方法(
    -ei
    )也不起作用,因为perl会尝试将
    i
    作为程序执行,这会导致编译失败

  • s/../../

    这是perl的基于正则表达式的替换运算符。它包含四个参数。第一个位于运算符之前,如果未指定,则使用默认值
    $\uuu
    。第二个和第三个位于
    /
    符号之间。第四个在最后一个
    /
    之后,在本例中为
    g

    • 在我们的代码中,第一个参数是
      $\
      ,它是perl中的默认循环变量。如上所述,
      -p
      标志将我们的程序包装在
      while()
      中,它创建了一个
      while
      循环,每次从输入读取一行(
      )。它隐式地将这一行分配给
      $\uuu
      ,如果未指定,则所有接受单个参数的命令都将使用这一行(例如:仅调用
      print;
      将实际转换为
      print$\uu;
      )。因此,在我们的代码中,
      s/../../
      操作符在输入文件的每一行上操作一次

    • [^[:ascii:]
      第二个参数是要在输入字符串中搜索的模式。此模式是一个正则表达式,因此
      []
      中包含的任何内容都是括号表达式。本节可能是本示例中最复杂的部分,因此我们将在最后详细讨论它

    • 第三个参数是替换字符串,在我们的例子中是空字符串,因为我们希望删除所有非ascii字符

    • g
      第四个参数是替换运算符的修改器标志。
      g
      标志指定替换应该是输入中所有匹配项的全局替换。如果没有此标志,将仅替换第一个实例。其他可能的标志是
      i
      用于不区分大小写的匹配,
      s
      m
      ,它们仅与多行字符串相关(我们这里有单行字符串),
      o
      指定应预编译模式(这在这里对长文件可能有用),和
      x
      ,它指定模式可以包括空格和注释,以使其更可读(但如果是这样的话,我们不应该在一行上编写程序)

  • filename

    这是包含以下非ascii字符的输入文件:
    $ gcc -W source_code.c -o convert
    
    $ ./convert