【问题标题】:Bash/Linux Find non-ASCII character in a .txt file and replace it with an ASCII characterBash/Linux 在 .txt 文件中查找非 ASCII 字符并将其替换为 ASCII 字符
【发布时间】:2017-06-20 22:25:24
【问题描述】:

我有一份从海洋仪器卸载的文件列表。出于某种原因,有时会在应插入 ASCII 字符的位置插入非 ASCII 字符。我找到了坟墓-E (È),在经度记录中应该有一个 W 来表示西半球。

数据如下所示:

CUMSECS Date UTC    Time UTC    Date Local  Time local  Z (m)   Target Z    Z Bot   Temp    PAR Salin   Ang VelX    Ang VelY    Ang VelZ    Pump +  Pump -  Gctr    Fix secs    Date UTC    Time UTC    Date Local  Time Local  Lat LatD    Latm        Lon LonD    Lonm        DOP Temp    PAR Salin   Batt V      CMD secs    Date Local  Time Local  No. Cmds
526068034   09/01/16    18:00:34    09/01/16    11:00:34     3.75    2.69    
3.75     0.29    0.000000    0.00   -12 -70 -50 0   5   10
526068039   09/01/16    18:00:39    09/01/16    11:00:39     3.75    2.69    
3.75     0.29    0.000000    0.00   -12 -70 -50 0   5   10
526068044   09/01/16    18:00:44    09/01/16    11:00:44     3.74    2.69    
3.75     0.29    0.000000    0.00   -12 -70 -50 0   5   10
526068049   09/01/16    18:00:49    09/01/16    11:00:49     3.73    2.69    
3.75     0.29    0.000000    0.00   -30732  13588   31909   60399   7538    -82
543622771   03/23/17    22:19:31    03/23/17    15:19:31    38.31877    38  
19.1262 N   123.07136   123  4.2812 È   23.6    115.06     0.0000   96.00   
121.718 
547764151   05/10/17    20:42:31    05/10/17    13:42:31     0.03   16.00   
127.00  13.68   1074.904320 33.56   -4908   -3976   261 1   0   0
547764152   05/10/17    20:42:32    05/10/17    13:42:32     0.00   16.00   
127.00  13.68   1074.904320 33.56   -4908   -3976   261 1   0   0

我可以使用以下 Bash 行找到非 ASCII 字符 pcregrep -n '[^\x00-\x7F]' 170510_ocean_Copepod.txt

我想遍历一系列文件,找到这些字符,并将它们替换为“W”,以便随后将它们读入 R 并整体处理它们。或者,解决 R 在尝试读取这些文件时返回的错误(“位置中的多字节字符串......”)对于我的目的同样有效。非常感谢任何帮助。

【问题讨论】:

  • pcregrep -n '[^\x00-\x7F]' 170510_ocean_Copepod.txt | sed 's/[^\x00-\x7F]/W/g' 但这会在 sed 调用非法字节序列时返回错误
  • 您是否尝试过更改read.tablefileEncoding 参数?
  • 我已经尝试过 R 中的 fileEncoding 和 Encoding 路由(明确称其为 latin1 或 utf8),但无济于事。我对编码问题的理解可能有限,但据我所知,这并不是真正的编码问题。也许我错了——有什么想法吗?
  • cat <file> | tr 'È' 'W'
  • 所以我永远无法让 tr 方法工作——它总是返回一个“错误:非法字节序列”。但是,我按照 Kind Stranger 建议的方式使用了 iconv,它是成功的。最后,我没有替换字符,但能够获得 R 可识别的编码,以便我可以批处理隐藏那些小的多字节字符的文件。如果有人对如何实际替换字符有任何想法(或者为什么我在 MacOSX bash 终端会话中遇到这样的错误),那将帮助我使我的代码更加健壮。目前,我的研究还停留在一个半球。

标签: r regex bash ascii non-ascii-characters


【解决方案1】:

我认为问题在于 utf-8 中的 È 是一个由 \xc3\x88sed 组成的多字节字符,无论出于何种原因似乎都无法处理这个问题。正如@Jack 所建议的那样,tr 可能是一个更好的工具(在 bash 中针对没有 pcregrep 的 Windows 进行了测试):

user@PC:~$ grep -P '[^\x00-\x7f]' | tr 'È' 'W'
19.1262 N   123.07136   123  4.2812 WW   23.6    115.06     0.0000   96.00

请注意,它确实将两个字节分别转换为W

另一种方法是使用iconv 转换整个文件。 iso-8859-15 (latin-9) 是单字节字符编码的一个例子。使用iconv 转换文件的命令是:

iconv -f utf-8 -t iso-8859-15 -o <converted-file> <input-file>

【讨论】:

  • 另一种选择是使用iconv 转换文件编码,然后在r 中读取文件
  • 看起来带有 tr 的 shell 方法可以工作,但我也对编码感到好奇。你知道我可以转换成什么编码不包含任何多字节字符并且可以随后读入 R 吗?感谢您的有用建议。
  • 看起来 tr 方法也被挂断了。我收到一个错误:tr: Illegal byte sequence 是否使用 cat &lt;file&gt; | tr 'È' 'W'pcregrep -n '[^\x00-\x7F]' 170510_ocean_Copepod.txt | tr 'È' 'W'。如果我使用 cat 方法,它会在返回错误之前打印到 È 所在的行。
  • @SeaSpider,添加了有关iconv的详细信息
【解决方案2】:

您可以使用sedÈ 替换为W

sed 's/È/W/g' 170510_ocean_Copepod.txt

【讨论】:

    猜你喜欢
    • 2010-12-30
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-02-13
    • 2021-12-22
    • 2013-01-29
    • 1970-01-01
    相关资源
    最近更新 更多