Sed未查找/替换目录中的所有字符

Sed未查找/替换目录中的所有字符,sed,Sed,我正在尝试查找和替换目录中许多文本文件中的单个字符。对于可能出现的重复,我深表歉意,但我一直无法在其他sed线程中找到答案 我使用自制软件安装gnu sed,并使用以下命令: find . -name "*.txt" -exec gsed -i -e 's/ñ/–/g' '{}' \; 我有一个“测试”文件,其中包含我需要在目录中替换的字符,这些字符都已正确找到并替换。但是其他文本文件中的其他字符不是。e、 g.“我们要去丹麦尼奥尔”(尼奥尔也没有被发现/取代) 为什么会这样?我怎样才能修好它

我正在尝试查找和替换目录中许多文本文件中的单个字符。对于可能出现的重复,我深表歉意,但我一直无法在其他sed线程中找到答案

我使用自制软件安装gnu sed,并使用以下命令:

find . -name "*.txt" -exec gsed -i -e 's/ñ/–/g' '{}' \;
我有一个“测试”文件,其中包含我需要在目录中替换的字符,这些字符都已正确找到并替换。但是其他文本文件中的其他字符不是。e、 g.“我们要去丹麦尼奥尔”(尼奥尔也没有被发现/取代)

为什么会这样?我怎样才能修好它?谢谢大家!

编辑-输出

$ od -c filethatworks.txt | head -2
0000000    –  **  **  \n   –  **  **  \n   “  **  **  \n   “  **  **  \n
0000020    —  **  **  \n   —  **  **  \n   -  \n   “  **  **  \n   “  **
$ od -c filethatdoesnot.txt | head -2
0000000    T   h   o   s   e       b   l   e   s   s   e   d       d   a
0000020    y   s       o   f       s   u   m   m   e   r       a   r   e
对于有效的文件,file命令返回

test.txt: UTF-8 Unicode text
对于一个没有:

ca001_mci_17071971.txt: Non-ISO extended-ASCII text, with very long lines, with CRL
F line terminators
人物是人类的概念。在计算机文件中表示字符时,需要对其进行编码。编码将每个字符与一个称为码点的整数相关联

例如,以字符“ă”为例(这是小写字母“a”,上面有一个短音符,在罗马尼亚语中用于元音
/ə/
);在过去的MS-DOS中,我们经常使用一种称为“”的编码,其中“ă”的代码点为199。然后Windows出现了,在Windows上我们经常使用一种称为“”的编码,其中“ă”的代码点为227。然后是Unicode,Unicode中的“ă”有代码点259

由于Unicode代码点的值可以大于255,因此必须有一种方法使用值介于0和255之间的字节来表示它们。这些方法被称为“Unicode转换格式”(UTF),其中使用最广泛的是(在Linux中非常流行)和(两种类型,little和big-endian,在Windows上非常流行)。在UTF-8中,“ă”表示为两个字节,值为196和131(根据UTF-8的规则,这两个字节一起表示代码点259);在little-endian UTF-16中,“ă”由两个字节表示,值为3和1(根据little-endian UTF-16的规则,这两个字节一起表示代码点259)

要点是为了理解文本文件,您需要知道(1)使用了什么编码,以及(2)对于Unicode,使用了什么转换格式。现在,在Linux和Web上,我们非常接近一个共识,即所有文本都用UTF-8表示;尽管如此,旧文件仍然存在,偶尔新文件来自Windows,因此有一个非常好的程序(在Linux和上都可用)用于将文本文件从一种编码转换为另一种编码

例如,假设您的问题文件是用Windows-1252编码的(Windows文档也称为ANSI,尽管美国国家标准协会与此无关),您可以说

iconv -f windows-1250 -t utf-8 ca001_mci_17071971.txt | gsed -e 's/ñ/–/g' '{}'

遗憾的是,没有办法使用sed-i;您必须编写一个临时输出文件,然后在检查一切正常后,将临时输出文件重命名到源文件的顶部。

涉及unicode时,事情总是会变得混乱。:)您能否在问题中包括
od-c filethatworks.txt | head-2
od-c filethatnot.txt | head-2
的输出,以及
file
命令指向这些文件时返回的内容?我怀疑您遇到的问题更多地与您使用的
gsed
有关。命令行中的
ñ
会转换为一系列字节,这些字节可能与文件中的序列不同,具体取决于编码。我担心这是unicode问题…已编辑以包含这些字节,抱歉,我不熟悉使用命令行等。请查看AlexP的答案
iconv
也是我要建议的。您可能需要做一些实验或进一步研究,以确定哪些输入编码适用于不适用的文件。根据AlexP的建议,您可能无法信任
sed
来处理
US-ASCII
之外的特殊字符。仔细检查你的结果。回答得很好。比我还在脑子里想的要好多了+1. :) 我要指出,OP提到的“自制”可能表明macOS的使用,它通常使用BSD工具的变体。。除非GNU版本是手动安装的,如自制或Macports。
iconv
二进制文件分别通过命令
brew install libiconv
port install libiconv
安装。感谢您的深入回答!太好了@ghoti是的macOS,谢谢:)在玩过iconv之后,我想知道是否最好使用{iconv-f windows-1250-t utf-8 ca001_mci_17071971.txt>outputfile.txt}将整个文件转换为utf-8?这似乎有效,但我可能会在以后遇到问题…@ConfusedfromWandsworth:我建议您维护所有以UTF-8编码的文本文件;如果原始文件具有不同的编码,我将创建一个UTF-8编码副本,通过在名称和后缀之间添加
.UTF-8
来命名,例如,
ca001\u mci\u 17071971.UTF-8.txt
,以便您知道它来自何处。