如何使用awk读取每n个字符而不是每行的文件?

时间:2016-03-03 09:01:07

标签: linux bash file optimization awk

这是file.txt

的内容
hello bro
my nam§
is Jhon Does

该文件还可以包含non-printable characters (for example \x00, or \x02),如您所见,这些行的长度不一样。

然后我想每5个字符读取一次而不需要计数换行符。我想用这样的东西用awk:

awk -v RS='' '{
  s=s $0;
}END{
  n=length(s);

  for(x=1; x<n; x=x+5){
    # Here I will put some calcs and stuff

    i++;
    print "line " i ": #" substr(s,x,5) "#"
  }
}' file.txt

输出如下:

line 1: #hello#
line 2: # bro
#
line 3: #my na#
line 4: #m§
is#
line 5: # Jhon#
line 6: # Does#

它完美无缺,但输入文件非常大,因此性能非常重要。

简而言之,我正在寻找类似的东西:

awk -v RS='.{5}' '{ # Here I will put some calcs and stuff }'

但它不起作用。

另一种可行的方法:

xxd -ps mifile.txt | tr -d '\n' | fold -w 10 | awk '{print "23" $0 "230a"}' | xxd -ps -r

您有任何想法或替代方案吗?谢谢。

4 个答案:

答案 0 :(得分:1)

假设您正在使用普通字符,则可以使用perl和binmode。

use strict;
use warnings;

open my $fh, '<', 'test'; 
#open the file.
binmode $fh;
# Set to binary mode
$/ = \5;
#Read a record as 5 bytes

while(<$fh>){
#Read records
        print "$_#"
        #Do whatever calculations you want here
}

对于扩展字符集,您可以使用UTF8并读取每5个字符而不是字节。

use strict;
use warnings;

open my $fh, '<:utf8', 'test';
#open file in utf8.
binmode(STDOUT, ":utf8");
# Set stdout to utf8 as well

while ((read($fh, my $data, 5)) != 0){
#Read 5 characters into variable data
    print "$data#";
    #Do whatever you want with data here
}

答案 1 :(得分:1)

如果你对 Python 没问题,你可以试试这个

f = open('filename', 'r+')
w = f.read(5)
while(w != ''):
        print w;
        w = f.read(5);
f.close()

答案 2 :(得分:1)

所以你问过如何使用awk 每n个字符而不是每行读取一个文件。

解决方案

如果您有一个现代gawk实施,请使用FPAT

  

通常,当使用FS时,gawk将字段定义为部分   在每个字段分隔符之间发生的记录。换句话说,FS   定义字段不是什么,而不是字段是什么。然而,   有时候你真的想用它们来定义字段   是,而不是它们不是。

代码:

gawk 'BEGIN{FS="\n";RS="";FPAT=".{,5}"}
            {for (i=1;i<=NF;i++){
               printf("$%d = <%s>\n", i, $i)}
            }' file

检查demo

答案 3 :(得分:1)

我不确定我理解你想要什么,但是这个输出和你说的问题中的脚本完全相同,所以希望这就是它:

$ awk -v RS='.{5}' 'RT!=""{ print "line", NR ": #" RT "#" }' file
line 1: #hello#
line 2: # bro
#
line 3: #my na#
line 4: #m§
is#
line 5: # Jhon#
line 6: # Does#

以上使用GNU awk进行多字符RS和RT。