【问题标题】:Delete lines from file with SED or AWK使用 SED 或 AWK 从文件中删除行
【发布时间】:2023-03-05 00:26:01
【问题描述】:

我见过很多变种,很困惑如何解决这三个问题。

  1. 从文件中删除除第一行之外的所有行
  2. 从文件中删除带有行号的行
  3. 从具有一系列行号的文件中删除行

【问题讨论】:

    标签: regex shell unix sed awk


    【解决方案1】:

    使用 sed:

    删除第一行:

    sed '1d' file-name
    

    删除第 10 行:

    sed '10d' file-name
    

    删除第 5 行到第 10 行

    sed '5,10d' file-name
    

    以上所有 sed 命令都会在标准输出上写入输出,您可以根据需要重定向到另一个文件,或者使用 sed 的 -i 标志来内联编辑文件。

    【讨论】:

    • 删除除第一行以外的所有行sed '2,$d' filename,或sed '1!d' filename,或sed -n '1p' filename
    • @Beta,前两个完全正确,但第三个只会打印第一行。
    • @dubiousjim: Print first line onlydelete all lines but the first 相同,这就是为什么 sed -n '1p' 也是正确的。
    • @anubhava,对不起,精神故障。我以为你在尝试做别的事情;不知道我是凭什么这么想的。
    • 在不破坏/创建表的情况下加载 sql 转储的救星。非常感谢:)
    【解决方案2】:

    使用 awk:

    # delete line 1
    awk 'NR == 1 {next} {print}' file
    
    # delete line number stored in shell variable $n
    awk -v n=$n 'NR == n {next} {print}' file
    
    # delete between lines $a and $b inclusive
    awk -v m=$a -v n=$b 'm <= NR && NR <= n {next} {print}' file
    

    为了节省一些字符,{print} 可以替换为 1

    要覆盖原始文件,你必须这样做

    awk '...' file > tmpfile && mv tmpfile file
    

    【讨论】:

    • 好的,这是可行的,但是这些行只是打印出来而不是保存到文件中?
    • 要删除第 1 行,请使用 awk 'NR!=1'。默认操作是打印该行。您的所有“{next} {print}”字词都可以删除。
    【解决方案3】:

    如果你的系统有 bash,你就可以使用它。背后的基本思想是设置一个计数并在迭代文件时增加该计数。

    1) 从文件中删除除第一行之外的所有行

    read -r line < file; echo "$line" > temp && mv temp file
    

    2) 从文件中删除行号为一行

    declare -i count=0
    while read -r line
    do
      ((count++))
      case "$count" in
        10) continue;;
        * ) echo "$line";;
      esac
    done < file > temp && mv temp file
    

    3) 从文件中删除行号范围为 10 到 20 的行

    declare -i count=0
    while read -r line
    do
      ((count++))
      if (( $c < 10 && $c > 20 ));then
        echo "$line";;
      fi
    done < file > temp && mv temp file
    

    【讨论】:

    • 你使用它的方式,read -r 仍然会去除前导和尾随空格。你需要做IFS= read -r line。此外请注意,从 shell 脚本中,此方法对于小文件更快,因为它避免了分叉,但对于大文件则较慢,因为 read 本质上效率低下,通常一次读取一个字节,或者每次调用一次读取和 lseek 调用,并且bash 中的字符串处理往往效率低下(在其他 shell 中效率较低)。
    • @jilles,谢谢我在这些情况下忘记了 IFS=。是的,我知道read 对带有bash 的大文件效率低下。如果 OP 的文件很大并且性能有问题,那么使用更好的工具。
    猜你喜欢
    • 2013-10-08
    • 2016-02-04
    • 2023-01-26
    • 1970-01-01
    • 2021-03-22
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多