2010-07-26 134 views
40

我想从文件中删除所有非ASCII字符。从CSV中删除非ASCII字符

我发现一个解决方案与tr,但我想我需要写回修改后的文件。

我需要在相对良好的表现下做到这一点。

有什么建议吗?

+0

你可以提供一个链接到一个衬管TR? – 2016-06-28 19:00:41

+0

的OP大概(?)意味着不可打印的字符(CTRL-C,Unicode数字U + 0002,是一个ASCII字符)。这个问题还应该指定语言环境 - 如果没有这些信息,人们可能(应该)认为他的意思是“C”语言环境。一个天真的答案是去除大于0x7f的任何字节 - 这将保留在C语言环境中不可打印的字符,但是完全合法的ASCII字符。由于这些原因使得它太模糊,我对这个问题低估了。 – Juan 2018-03-07 00:58:59

回答

30
# -i (inplace) 

sed -i 's/[\d128-\d255]//g' FILENAME 
+2

不得不改变它的sed -i 'S/[\ d128- \ D255] // G' FILENAME 和它的工作..感谢 – Sujit 2010-07-26 18:57:06

+0

@Sujit:需要注意的是'sed的-i'还是创建一个中间文件。它只是在幕后进行。 – 2010-07-26 19:57:47

+0

@丹尼斯 - 那么更好的解决方案是什么? – Sujit 2010-07-26 20:43:25

57

一个Perl oneliner会做:perl -i.bak -pe 's/[^[:ascii:]]//g' <your file>

-i说,该文件将被就地编辑,并且备份是要与扩展.bak保存。

+1

这一个是也可用'stdin'作为输入。 – h3xStream 2012-08-08 14:59:52

+2

perl解决方案比sed解决方案更快。尝试使用sed更新122 GB文件需要3个小时,而perl对我来说花了不到2个小时。 – Roger 2014-09-15 19:01:36

+0

我无法让'sed'解决方案在我的环境中工作(Ubuntu gnu sed 4.2.2),但是它的工作方式就像一个魅力。 – 2015-06-01 12:02:54

3

作为sed或perl的替代方法,您可以考虑使用ed(1)和POSIX字符类。

注:ED(1)整个文件读入内存就地编辑它,所以真正的大文件,你应该使用SED -i ...,Perl的-i ...

# see: 
# - http://wiki.bash-hackers.org/doku.php?id=howto:edit-ed 
# - http://en.wikipedia.org/wiki/Regular_expression#POSIX_character_classes 

# test 
echo $'aaa \177 bbb \200 \214 ccc \254 ddd\r\n' > testfile 
ed -s testfile <<< $',l' 
ed -s testfile <<< $'H\ng/[^[:graph:][:space:][:cntrl:]]/s///g\nwq' 
ed -s testfile <<< $',l' 
11
sed -i 's/[^[:print:]]//' FILENAME 

而且,这种行为像DOS2UNIX的

+9

不起作用。 [:print:]与ASCII不一样。有许多可打印的非ASCII字符。 – 2014-06-18 15:17:50

+0

此外g修饰符丢失。只有第一个不可打印的字符会被删除。 – proski 2017-11-30 00:18:18

+0

@JasonC还有许多不可打印的ASCII字符。原来的问题可能很不健全。 – Juan 2018-03-07 01:21:33

10

我发现下面的解决方案是工作:

perl -i.bk -pe 's/[^[:ascii:]]//g;' filename 
2
awk '{ sub("[^a-zA-Z0-9\"[email protected]#$%^&*|_\[](){}", ""); print }' MYinputfile.txt > pipe_out_to_CONVERTED_FILE.txt 
4

我使用的是一个非常小的busybox系统,其中tr或POSIX字符类不支持范围,所以我必须以糟糕的老式方式来做。下面是与sed的解决方案,从文件中剥离所有非打印非ASCII字符:

sed -i 's/[^a-zA-Z 0-9`[email protected]#$%^&*()_+\[\]\\{}|;'\'':",.\/<>?]//g' FILE 
-1

我很欣赏我在这个网站上找到的提示。

但是,在我的Windows 10,我不得不使用这个工作双引号...

sed -i "s/[\d128-\d255]//g" FILENAME

注意到这些细节...

  1. 对于文件名中的全部路径\名称需要引用 这并没有工作 - %TEMP%\"FILENAME" 这样做 - %TEMP%\FILENAME"

  2. SED叶子后面在当前目录下的临时文件名为sed的*

+0

注意:此答案适用于gnu sed,但不适用于其他版本的sed(例如bsd)。鉴于在这个答案中提到的副作用,它似乎是一个奇怪的Windows编译版本,试图模仿GNU SEED。或者用户在无关的外壳问题上混淆了水。 – Juan 2018-03-07 01:30:41

3

这为我工作:

sed -i 's/[^[:print:]]//g' 
+0

我在终端中仍然收到像007F这样的Unicode字符。 – 2017-12-21 05:35:26

+0

@KatasticVoyage您的语言环境设置为(LANG,LC_CTYPE)? – Juan 2018-03-07 00:43:38

1

尝试tr而不使用sed

tr -cd '[:print:]' < file.txt 
+1

OP特别提到他不想使用tr(因为他想要一个sed -i伪装成的“就地”转换 - 真正写入临时文件并在后台重命名)。所以这个答案对OP没有帮助。但是...对于那些想要使用tr的人,你可能想要保留换行符(这里显示的20180228版本没有)。然而,一个简单的调整会保留换行符和回车符:'tr -cd'[:print:] \ n \ r' Juan 2018-03-07 00:08:28