使用SED或AWK从文件中删除行

17

我看到了很多不同的问题变体,对如何解决这3个问题感到非常困惑。

  1. 从文件中删除除第一行之外的所有行
  2. 根据行号从文件中删除一行
  3. 使用一系列行号从文件中删除行
3个回答

31

使用sed:

删除第一行:

sed '1d' file-name

删除第10行:

sed '10d' file-name

删除第5到10行

sed '5,10d' file-name

所有上面的sed命令输出都将写入stdout,如果你想的话可以将其重定向到另一个文件,或者使用sed的-i标志进行内联编辑。


1
要删除除第一行以外的所有行,可以使用以下命令:sed '2,$d' filenamesed '1!d' filename或者sed -n '1p' filename - Beta
@Beta,前两个是完全正确的,但第三个将只打印第一行。 - dubiousjim
1
@dubiousjim:仅打印第一行删除除第一行外的所有行是相同的,这就是为什么sed -n '1p'也是正确的。 - anubhava
@anubhava,抱歉,我有点糊涂了。我以为你在尝试做其他事情;不知道我以什么为基础这样想。 - dubiousjim
1
无需销毁/创建表格即可加载SQL转储文件的救星。非常感谢 :) - Groxx

10

使用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
好的,这个程序可以运行,但是这些行只是被打印出来了,没有保存到文件中? - bluetickk
3
要删除第一行,请使用awk 'NR!=1'。默认操作是打印该行。可以删除所有的“{next} {print}”术语。 - Andrew Dalke

0

如果你的系统有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 脚本中使用此方法更快,因为它避免了 fork,但对于大文件来说则较慢,因为 read 本质上是低效的,并且通常每次调用只读取一个字节或执行一次读取和 lseek 调用,并且在 bash 中字符串处理往往是低效的(在其他 shell 中则相对不那么低效)。 - jilles
@jilles,谢谢提醒我这些情况下需要使用IFS=。是的,我知道在bash中对于大文件来说,read效率低下。如果OP的文件很大且性能是一个问题,那么请使用更好的工具。 - bash-o-logist

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接