我正在从可怕的文本数据(2GB csv文件)开始工作,其中包括几乎所有转义字符0x00-0x1F都散布在整个文件中。我试图将其读入R进行处理但不能由于EOF(0x04):
Warning message:
In scan(file, what, nmax, sep, dec, quote, skip, nlines, na.strings, :
EOF within quoted string
所以我认为sed可以很好地删除文件中所有不可打印的垃圾,但是如何在sed语法中表示转义字符似乎有些奇怪。我尝试了以下所有似乎不起作用的内容:
仅包括指定的字符:
sed 's/[^a-zA-Z 0-9`~!@#$%^&*()_+\[\]\\{}|;'\'':",.\/<>?]//g' IN.csv > OUT.csv
以十进制或十六进制标识不可打印的范围:
cat IN.csv | sed 's/[\d0-\d31]//g' > OUT.csv
cat IN.csv | sed s/[$'\x00'-$'\x1F']//g OUT.csv
cat IN.csv | sed 's/\x00-\x1F//g' > OUT.csv
并使用 Ctrl-V Ctrl-D 生成:
cat IN.csv | sed s/^D//g > OUT.csv
所有命令似乎都在执行,但生成的文件输出不会删除不可打印的字符,并且似乎以意外的方式更改输出。
我发现工作是这样的:
cat IN.csv | sed 's/'`echo -e "\x04"`'//g' > OUT.csv
或者这个:
cat IN.csv | sed 's/\x04//g' > test3.csv
但是这仅适用于单个转义字符。有没有更好的方法在一个范围内同时处理所有不可打印的字符而不必为每个不可打印的执行1个命令?我假设我不能正确输入范围的语法。
答案 0 :(得分:2)
对于删除(和音译),有一个更好的工具叫tr
(翻译或删除字符)。您可以使用以下方法删除不可打印的字符:
cat IN.csv | tr -cd '\11\12\15\40-\176' > OUT.csv
-d
- 删除提到的字符,-c
会反转范围。
或使用POSIX [:print:]
:
cat IN.csv | tr -cd '[:print:]' > OUT.csv
答案 1 :(得分:0)
您可以尝试awk
:
awk '{gsub(/[[:punct:]]/,"")}1' your_file
或尝试sed
:
sed "s/[^a-z|0-9]//g;" orig_file > new_file
或尝试perl:
perl -pe 's/[^A-Za-z0-9\s]//g' orig_file > new_file