我有一个由第三方提供的巨大文件,它似乎是在类似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
。
谢谢!
答案 0 :(得分:4)
由于^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
0000020