【问题标题】:How can I delete specific lines using awk/sed based on the contents of another file如何根据另一个文件的内容使用 awk/sed 删除特定行
【发布时间】:2014-04-16 14:36:51
【问题描述】:

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

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

我需要删除总共 2073 行。尽管我无法找到与此类似的示例,但我已尝试四处搜索如何执行此操作。

感谢您的帮助。

【问题讨论】:

    标签: bash shell debian


    【解决方案1】:

    假设要删除的行号在文件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 命令读取删除命令并将操作应用于大数据文件。

    【讨论】:

    • 我猜你误读了这个问题。标题具有误导性。数据文件包含要删除的行号列表。
    • @devnull:没有读过这个问题可能会更准确。我已经重写了答案。
    • 耶,sed 开车 sed!这很有趣:)
    • @gniourf_gniourf:写程序比写程序更有趣……:D
    【解决方案2】:

    使用 awk:

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

    【讨论】:

      【解决方案3】:

      ed 是标准编辑器。

      这里可以驱动ed 进行编辑(就地):

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

      这将打开文件fileed,读取包含行号的文件lines,检查每个读取的行确实是一个数字,然后给ed 删除该数字的命令, 完成后请ed 写信并退出wq

      您可能希望将 [[ $line =~ ^[[:digit:]]+$ ]] || continue 行替换为:

      [[ $line =~ ^[[:digit:]]+$ ]] || { printf >&2 "*** WARNING: Line %d not deleted\n" "$line"; continue; }
      

      以便在文件lines 中存在无效行时得到警告。


      请务必阅读 glenn jackmann 的评论:

      我听说 ed 的一些旧实现不接受 wq 作为单个命令:printf "%s\n" w q

      YMMV.

      【讨论】:

      • 我听说ed 的一些旧实现不接受wq 作为单个命令:printf "%s\n" w q
      猜你喜欢
      • 2018-08-25
      • 2013-10-08
      • 2013-04-05
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多