我看到了很多不同的问题变体,对如何解决这3个问题感到非常困惑。
- 从文件中删除除第一行之外的所有行
- 根据行号从文件中删除一行
- 使用一系列行号从文件中删除行
使用sed:
删除第一行:
sed '1d' file-name
删除第10行:
sed '10d' file-name
删除第5到10行
sed '5,10d' file-name
所有上面的sed命令输出都将写入stdout,如果你想的话可以将其重定向到另一个文件,或者使用sed的-i
标志进行内联编辑。
使用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
如果你的系统有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 中则相对不那么低效)。 - jillesbash
中对于大文件来说,read
效率低下。如果OP的文件很大且性能是一个问题,那么请使用更好的工具。 - bash-o-logist
sed '2,$d' filename
、sed '1!d' filename
或者sed -n '1p' filename
。 - Beta仅打印第一行
与删除除第一行外的所有行
是相同的,这就是为什么sed -n '1p'
也是正确的。 - anubhava