1

我有一个包含单个示例字符串 ABCDEFGHI 的大文件(示例长度为 10 个字符)。实际文件长度可能是数百万个字符。

我想将字符串拆分为具有预定长度的多行,但是在拆分字符时一次移动 1。这意味着拆分后没有。行数 = 字符串长度 - 分割大小 + 1

例如,如果我一次将其拆分为 3 个字符,则需要输出

ABC
BCD
CDE
DEF
...

如果我分成 4 个字符,那么

ABCD
BCDE
CDEF
DEFG

使用 shell 命令或脚本进行这种拆分的最佳方法是什么?

感谢您的任何提示

4

5 回答 5

3

你可以尝试这样的事情:

gawk -v FS="" '{
    r=3 # Set the length
    s=1 # Set the start point
    while(s<=NF-r+1) { 
        for (i=s;i<r+s;i++) { 
            printf $i 
        }
        s++
        print ""
     }
}'

测试:

$ echo "ABCDEFGHI" | gawk -v FS="" '{r=4; s=1; while(s<=NF-r+1) { for (i=s;i<r+s;i++) printf $i ; s++; print ""}}'
ABCD
BCDE
CDEF
DEFG
EFGH
FGHI
$ echo "ABCDEFGHI" | gawk -v FS="" '{r=3; s=1; while(s<=NF-r+1) { for (i=s;i<r+s;i++) printf $i ; s++; print ""}}'
ABC
BCD
CDE
DEF
EFG
FGH
GHI
于 2013-05-31T14:47:07.950 回答
2

另一个基于 awk 的选项,涉及substr

echo 'abcdefgh' |
awk -v limit=3  'BEGIN{FS=""}; 
{value=$0; for (i=1; i<= NF-limit +1; ++i) print substr(value, i, limit)}'

abc
bcd
cde
def
efg
fgh
ghi
于 2013-05-31T16:07:37.760 回答
2

这是sed(in bash)的一种方式:

GNU sed

sed -r ':a;s/([^\n])([^\n]{'$(( n-1 ))'})([^\n])/\1\2\n\2\3/;ta' filename

POSIX sed(我认为):

sed ':a;s/\([^\n]\)\([^\n]\{'$(( n-1 ))'\}\)\([^\n]\)/\1\2\n\2\3/;ta' filename

输出:

  • n=3

    ABC
    BCD
    CDE
    DEF
    EFG
    FGH
    GHI
    
  • n=4

    ABCD
    BCDE
    CDEF
    DEFG
    EFGH
    FGHI
    
于 2013-05-31T15:07:35.310 回答
0

使用 python 你可以写这样的东西:

import itertools

filename = "myfile"
length = 4
with open(filename, 'r') as f:
    out = ''
    # get your input character by character
    for c in itertools.chain.from_iterable(f):
        # append it to your output buffer
        out += c
        # if your buffer is more than N characters, remove the first char
        if len(out) > length:
            out = out[1:]
        # if your buffer is exactly N characters, print it out (or do something else)
        if len(out) is length:
            print out
    # if the last iteration was less than N characters, print it out (or do something else)
    if len(out) < length:
        print out

其中 file 是一个包含字符串完整路径的字符串。您也可以使用raw_input()代替open()/read(). 使用 awk 肯定有一个巧妙的解决方案,但我需要 RTFM 来告诉你如何去做。

无论您的解决方案是什么,此算法都是一种很好的方法,因为您始终只为缓冲区保留最多 N+1 个字符,再加上一个用于新读取的字符。所以这个算法的复杂度O(n)与输入字符流是线性的( )。

于 2013-05-31T15:01:19.153 回答
0

虽然我通常不喜欢引入这样的重量级脚本语言,但 python 让这变得非常简单

$ cat test.py
#!/usr/bin/env python

from os import sys

n = int(sys.argv[1])
s = sys.argv[2]

while len(s) > 0:
    print s[:n]
    s = s[1:]

$ python test.py 3 abcdef
abc
bcd
cde
def
ef
f
$ python test.py 4 abcdef
abcd
bcde
cdef
def
ef
f
$

如果您想在字符用完后停止,可以将while条件更改为len(s) >= n

于 2013-05-31T15:10:46.217 回答