读取文件,每块阻止

时间:2014-10-29 22:39:04

标签: linux bash shell debian pipe

我正在尝试制作一个有效的脚本来读取每个块的(大)文件块,并将最后一个读取块的第一行保存在文件中。 在我的例子中,如果我想将文件传递给程序,这非常有用。我可以阻止它,然后在它之前停止的同一行开始(意思是相同的块行)。

这是脚本:

LINE_FILE=line-file
READ_FILE=the_file
BLOCK=1000
LN_SUP=$(cat $LINE_FILE)

####

trap "save_line ; exit" SIGHUP SIGINT SIGTERM SIGKILL

save_line()
{
    echo $LN_SUP > $LINE_FILE
}

block_cat()
{
    TEXT=$(tail -n+$LN_SUP $READ_FILE | head -n $BLOCK)
    echo "$TEXT"
    if [ -n "$TEXT" ]; then
        return 0
    else
        return -1
    fi
}

test()
{
    return 1
}

file_cat()
{
    >&2 echo "First line to read the file : $LN_SUP"
    block_cat $READ_FILE
    while [ $? -eq 0 ]; do
        LN_SUP=$(($LN_SUP + $BLOCK))  #Remember the new first line of the block
        block_cat $READ_FILE
    done
}

这实际上有效,但没有我想象的那么快。

这用于将输出传输到aircrack-ng,我的效率几乎降低了18%。

您认为有更好的方法吗?

1 个答案:

答案 0 :(得分:0)

也许会这样做:

#!/bin/bash

line_file=line-file
quantum=1000
file=the_file

die() {
    (($#)) && printf '%s\n' "$@"
    exit 1
}

[[ -e $line_file ]] || echo "0" > "$line_file"
[[ -f $line_file ]] || die "File \`$line_file' not found"
[[ -r $line_file ]] || die "Can't read file \`$line_file'"

read current_line < "$line_file"

[[ $current_line = *([[:digit:]]) ]] || die "Error in file \`$line_file'"
((current_line=10#$current_line))

callback() {
    printf '%s\n' "${mary[@]}"
    mary=()
    echo "$1" > "$line_file"
}

mapfile -O "$current_line" -s "$current_line" -t -c "$quantum" -C callback mary < "$file" && callback

它使用mapfile及其很少使用(并且不是众所周知的)回调和量子的东西。如果第一个块只有999行,请不要感到惊讶。其他的是1000行长。有这方面的解决方法,但我不认为这对你的情况非常重要。

我还没有真正尝试过,如果有任何缺陷,请告诉我。

这里有许多关于你原始问题的无用线。但是,这些只是错误处理和常规检查,不能伤害。你只能专注于此:

callback() {
    printf '%s\n' "${mary[@]}"
    mary=()
    echo "$1" > "$line_file"
}

mapfile -O "$current_line" -s "$current_line" -t -c "$quantum" -C callback mary < "$file" && callback

因此,每次读取quantum(此处为1000)行时,都会调用回调,第一个参数设置为将在回调后设置的数组索引。在此回调中,我们只是转储数组的内容,清除此数组,并在line_file中保存文件的位置。就这么简单。要获得文件的结尾,我们最后一次调用callback

执行mapfile时,-s "$current_line"告诉mapfile跳过那么多行,-O "$current_line"告诉mapfile开始在此索引处分配。