Linux 命令,用于替换 unicode 或非 ascii 字符以及不在管道之前或之后的双引号

Linux command to replace unicode or non ascii characters and also double quotes that are not preceding or following a pipe

提问人:Sergio Jimenez 提问时间:10/5/2023 最后编辑:tripleeeSergio Jimenez 更新时间:10/6/2023 访问量:68

问:

我有一些CSV文件,其中有一些用双引号括起来的字符串字段。问题是其中一些字段只是人们引入的解释或注释,因此我的加载过程可能会不喜欢许多非 ASCII(或 unicode)字符,并且文本中也可能有双引号。

我想删除所有非 ASCII 字符和一些双引号。文件的分隔符是,所以我想删除所有不在管道之前或之后的双引号。 我花了一些时间寻找类似的问题,但我找到的所有问题都不同,所以如果我问的问题已经回答了,请原谅我。|

输入文件示例:

SEP-23|3958|106xxx|Anonymous Account||IE - IT|000|000000|000|DEFAULT|"TI805 ""¬PID35032 â¿""" AWS Migration""|0000

我想要这样的结果行

SEP-23|3958|106xxx|Anonymous Account||IE - IT|000|000000|000|DEFAULT|"TI805 PID35032 AWS Migration"|0000

我正在运行一个有时可以解决问题的 sed 命令,但我必须运行它 x 次才能替换所有双引号,并且在这种情况下它不起作用,不确定是因为非 ASCII 字符还是其他原因

sed -i 's/\([^|]\)"\([^|]\)/\1\2/g' sample.csv
UNIX SED 正则表达式替换

评论

0赞 jhnc 10/5/2023
使用可以正确解析编码输入的 csv 风格的工具。如果您的注释可以包含任意 Unicode,则它们可能还可以包含换行符。|
0赞 jhnc 10/5/2023
您的示例输入似乎格式不正确。您连续有三个双引号,而不是紧接在之前或之后,并且有两个双引号在之前||

答:

1赞 tripleee 10/5/2023 #1

类似的东西似乎适用于您的测试用例。

$ sed 's/[^ -~]//g;s/|"/|<|<|</g;s/"|/>|>|>|/g;s/"//g;s/|<|<|</|"/g;s/>|>|>|/"|/g' <<\:
> SEP-23|3958|106xxx|Anonymous Account||IE - IT|000|000000|000|DEFAULT|"TI805 ""¬PID35032 â¿""" AWS Migration""|0000
:
SEP-23|3958|106xxx|Anonymous Account||IE - IT|000|000000|000|DEFAULT|"TI805 PID35032  AWS Migration"|0000

在你有工作脚本之前,可能不要使用(甚至通常没有)。您的尝试似乎甚至没有尝试对非 ASCII 字符等做任何事情。sed -i

一个正确的解决方法是将 mojibake 恢复为有用的文本,或者理想情况下让原始来源在没有 mojibake 的情况下提供数据,但通常那艘船已经航行了,你必须用你已经拥有的东西做你能做的事。

1赞 HatLess 10/5/2023 #2

sed

$ sed -E ':a;s/(\|"[^|]*)[[:punct:]]([^|]*"\|)| ( )/\1\2\3/;ta' <(iconv -c -t ascii input_file)
SEP-23|3958|106xxx|Anonymous Account||IE - IT|000|000000|000|DEFAULT|"TI805 PID35032 AWS Migration"|0000
0赞 Renaud Pacalet 10/6/2023 #3

使用 GNU :sed

sed -E 's/[^\x00-\x7f]//g;s/([^|])"+([^|])/\1\2/g'

(删除所有非 ASCII 字符和 2 个非字符之间的所有双引号字符串)。|

演示:

$ sed -E 's/[^\x00-\x7f]//g;s/([^|])"+([^|])/\1\2/g' <<< 'FOO|"BAR ""¬BAZâ¿"""|'
FOO|"BAR BAZ"|