Linux Shell命令按行长过滤文本文件


19

我有一个坏分区的30gb磁盘映像(请考虑dd if=/dev/sda1 of=diskimage),我需要从中恢复一些文本文件。像数据雕刻工具之类的工具foremost只能在标头定义明确的文件上使用,即不能在纯文本文件上使用,因此我不再依赖我的好朋友了strings

strings diskimage > diskstrings.txt 产生了一个3gb的文本文件,其中包含一串字符串(大多数是无用的东西)与我实际想要的文本混合在一起。

大部分杂物往往是很长的,不间断的乱码。我感兴趣的东西一定要小于16kb,所以我将按行长过滤文件。这是我正在使用的Python脚本:

infile  = open ("infile.txt" ,"r");
outfile = open ("outfile.txt","w");
for line in infile:
    if len(line) < 16384:
        outfile.write(line)
infile.close()
outfile.close()

此作品,但以供将来参考:是否有任何神奇的单行咒语(想想awksed),将通过过滤线路长度文件?

Answers:


28
awk '{ if (length($0) < 16384) print }' yourfile >your_output_file.txt

就像您自己的示例一样,将打印少于16 KB的行。

或者,如果您喜欢Perl:

perl -nle 'if (length($_) < 16384) { print }' yourfile >your_output_file.txt

好吧,那太简单了。谢谢。:)
叶丽昂

还添加了Perl版本:-)
Janne Pikkarainen 2012年

而且awk脚本可以写成awk 'length($0) < 16384' file > output,因为默认操作是打印行。
glenn jackman 2012年

8

这类似于Ansgar的答案,但在我的测试中速度稍快:

awk 'length($0) < 16384' infile >outfile

它与其他awk答案的速度相同。它依赖于print真实表达式的隐式,但不需要像Ansgar那样花费时间来拆分行。

请注意,AWK if免费提供给您。上面的命令等效于:

awk 'length($0) < 16384 {print}' infile >outfile

if像其他一些答案一样,没有明确的(或周围的花括号)。

这是在其中进行操作的方法sed

sed '/.\{16384\}/d' infile >outfile

要么:

sed -r '/.{16384}/d' infile >outfile

删除包含16384个(或更多)字符的任何行。

为了完整起见,以下是sed用于保存行数超过阈值的行的方法:

sed '/^.\{0,16383\}$/d' infile >outfile

2

您可以awk例如:

$ awk '{ if (length($0) < 16384) { print } }' /path/to/text/file

这将打印长于16K字符(16 * 1024)的行。

您还可以使用grep

$ grep ".\{,16384\}" /path/to/text/file

这将最多打印16K个字符的行。


不确定grep是否有这么好的主意-可以肯定,这是一个简单的regexp,但计算量却比昂贵awk。“有问题的人说:“我将使用正则表达式!”现在他有两个问题。” ;)
叶丽昂

这只是另一种方式。我发布的第一个选项是使用awk
哈立德

1
正则表达式+1,因为它打高尔夫球更好,并且不会让我阅读awk手册页=)
Ciro Santilli新疆改造中心法轮功六四事件2014年

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.