如何根据另一个文件的内容使用awk / sed删除特定行

时间:2014-04-16 14:36:52

标签: bash shell debian

如何根据另一个文件中包含的行号从文件中删除特定行?我知道如何通过在命令行上提供特定行来删除它们,但我不知道如何根据另一个文件中包含的行号删除特定行。包含行号的文件采用以下格式:

15768
15775
15777
15782
15784
15789
15791
15798
15800
15807
15809
15815
15817
15824
15826

我需要删除总共2073行。我试过四处寻找如何做到这一点虽然我无法得到类似的例子。

感谢您的帮助。

3 个答案:

答案 0 :(得分:3)

假设要删除的行号位于文件to-be-deleted中且数据位于big-data-file,则使用Bash process substitution

 sed -f <(sed 's/$/d/' to-be-deleted) big-data-file > smaller-data-file

内部sed 's/$/d'命令将行号转换为sed删除操作。外部sed命令读取删除命令并将操作应用于大数据文件。

答案 1 :(得分:2)

使用awk:

awk 'FNR==NR{a[$0];next} !(FNR in a)' f1 f2

答案 2 :(得分:1)

ed是标准编辑。

此处可以驱动ed进行编辑(就地):

#!/bin/bash

ed -s file < <(
    while read line; do
        [[ $line =~ ^[[:digit:]]+$ ]] || continue
        printf "%d d\n" "$line"
    done < lines
    echo "wq"
)

这将使用file打开文件ed,读取包含行号的文件lines,检查每个读取行是否确实是一个数字,然后提供给{{1删除该号码的命令,完成所有操作后,请ed编写并退出ed

您可能希望将wq行替换为:

[[ $line =~ ^[[:digit:]]+$ ]] || continue

以便在文件[[ $line =~ ^[[:digit:]]+$ ]] || { printf >&2 "*** WARNING: Line %d not deleted\n" "$line"; continue; } 中存在无效行时收到警告。


请务必阅读glenn jackmann的评论:

  

我听说lines的一些旧版实现不接受ed作为单个命令:wq

因人而异。