获取要从数组中删除的行号

时间:2014-05-09 17:31:09

标签: arrays bash sed

我正在尝试从一个巨大的文件中删除某些行,从阵列中删除行号。该文件的大小至少为2GB,我的数组大小也可以很大。我可以在没有for循环的情况下这样做吗?什么是最快的方式?     例如:

input:
>1
>2
>3
>4
>5

declare -a A=(2 3 5);

output: 
>1
>4

4 个答案:

答案 0 :(得分:1)

  

...从阵列中删除行号。

如果我理解正确,您的数组A包含要从输入中删除的行号。

您可以使用sed

sed $(printf "%dd;" "${A[@]}") inputfile

使用-i选项就地修改文件。

如果数组太大,请考虑使用进程替换:

sed -f <(printf "%dd;" "${A[@]}") inputfile

答案 1 :(得分:1)

我不会用普通的shell代码来做这件事。 sed 是编辑/转换文件的工具。

On-The-Fly从您的阵列创建一个sed-programm并就地编辑INPUTFILE( -i

for line in ${A[@]}; do
    echo ${line}d
done| sed -i -f /dev/stdin $INPUTFILE

答案 2 :(得分:0)

您可以使用grep -vf来获取此数组差异:

declare -a O=(1 2 3 4 5)
declare -a A=(2 3 5)

B=( $(grep -vf <(printf "%s\n" "${A[@]}") <(printf "%s\n" "${O[@]}")) )

<强>输出:

declare -p B
declare -a B='([0]="1" [1]="4")'
printf "%s\n" "${B[@]}"
1
4

答案 3 :(得分:0)

awk -v n=2,3,5 'BEGIN{split(n,nn,",")} !(NR in nn) {print}' input >output

在上文中,要删除的行列表作为变量n提供。 (我将其显示为以逗号分隔的格式,但其他格式也可以。)在BEGIN块中,此列表将转换为名为awk的{​​{1}}数组。 nn程序的其余部分只打印所有行号awk不在要排除的行数组中的行NR

如果nn以正确的哈希方式实现其成员资格测试,python的方式就是这样,那么上面应该很快。如果不是,不是。