传递一个很长的行号列表,从文件中删除

时间:2017-09-08 08:40:34

标签: bash sed

我正在尝试使用sed从一个非常大的文件中删除500多条非连续行。

我将这些行存储在list.txt文件中但我无法在for循环中使用

for i in `cat list`; do  echo 'sed -i -e ' \'"$i"d\'' huge_file.txt' ; done

因为原始文件中的行号每次sed删除一个并退出时都会更改。

我应该这样做:

sed -i -e '1d;2d;93572277d;93572278d; ......;nth '  huge_file.txt

有没有办法将该列表传递给文件中的sed

2 个答案:

答案 0 :(得分:2)

你可以试试awk:

awk -v s="2,3,..,n" 'BEGIN{n=split(s,t,",");for(i=1;i<=n;i++)d[t[i]]=1}
                    !d[NR]' huge.txt

您将逗号分隔的行号传递给awk -v,在awk中将其拆分为数组,并检查每一行,如果数组中的行号,则跳过。

使用小文件测试它,如果它按预期工作,你可以这样做:

awk -v '....' '....' huge.txt > tmp.txt && mv tmp.txt huge.txt

将更改写回原始输入文件。

更新

如果您在另一个文件中有500个行号,例如,行中的每个数字,您可以:

awk 'NR==FNR{a[$0]=1;next}!a[FNR]' ln.txt huge.txt

答案 1 :(得分:1)

如果仅针对单个特定任务(不常见),您可以使用以下GNU sed 方法(假设list.txt中的数字与换行\n):

sed -i "$(sed -z 's/\n/d;/g' list.txt)" huge_file.txt