我有一个由第三方提供的巨大文件,它似乎是在类似Windows/DOS的环境中生成的。文件的最后一行包含一个^Z字符。当我查看已处理的文件时,我注意到了这一点,最后一行包含一个^Z。我添加了一些逻辑来跳过输入中的这一行,它工作得很好,直到我将代码更改为接受来自stdin的输入,而不是文件。
下面是这个问题的一个简单的例子。当我对单个文件流进行行计数时,不管是否跳过^Z,它都报告正确的值:
unzip -j -p -qq file1.zip | perl -nle 'print' | wc -l
3451
unzip -j -p -qq file2.zip | perl -nle 'print' | wc -l
3451
unzip -j -p -qq file1.zip | perl -nle 'next if /^\cZ/; print' | wc -l
3450
unzip -j -p -qq file2.zip | perl -nle 'next if /^\cZ/; print' | wc -l
3450现在,当我试图同时处理两个文件时,我丢失了一条记录。我猜想这与^Z字符有关,但我想不出我能做些什么:
unzip -j -p -qq '*.zip' | perl -nle 'print' | wc -l
6901 ## this should have been 6902
unzip -j -p -qq '*.zip' | perl -nle 'next if /^\cZ/; print' | wc -l
6899 ## this should have been 6900 这些文件是巨大的(每个20+GB),它们将以3-6个文件组的形式读取,因此我希望避免逐一处理它们,然后再进行连接。关于如何避免^Z字符而不遇到上述问题,有什么想法吗?
我在Linux机器上。顺便说一句,在vim中打开文件不会显示最后一个记录(即^Z),而设置set ff=unix也不会改变这一点。因此,vim报告单个解压缩文件的3450行和组合解压缩文件的6900。
谢谢!
发布于 2015-12-30 19:44:05
由于^Z后面没有行尾,所以unzip正在生成
file1:1
file1:2
file1:3
^Zfile2:1
file2:2
file2:3
^Z因此,您删除了第二文件的第一行。您可以简单地删除^Z,而不是整个行。
perl -pe's/^\cZ//'也就是说,unzip -a正是针对这种情况而设计的。它不仅会为您剥去^Z,还会在必要时修复行尾。
$ unzip -j -p -qq z.zip a.txt | od -c
0000000 a b c \r \n d e f \r \n 032
0000013
$ unzip -j -p -qq z.zip b.txt | od -c
0000000 g h i \r \n j k l \r \n 032
0000013
$ unzip -j -p -qq z.zip | od -c
0000000 a b c \r \n d e f \r \n 032 g h i \r \n
0000020 j k l \r \n 032
0000026
$ unzip -j -p -qq -a z.zip | od -c
0000000 a b c \n d e f \n g h i \n j k l \n
0000020https://stackoverflow.com/questions/34535856
复制相似问题