如何使用 sed 删除文件的最后 n 行

2024-10-25 08:42:00
admin
原创
226
摘要:问题描述:我想从文件末尾删除n行。可以使用 sed 完成吗?例如,要删除第 2 到第 4 行,我可以使用$ sed '2,4d' file 但我不知道行号。我可以使用以下命令删除最后一行$sed $d file 但我想知道从末尾删除n行的方法。请告诉我如何使用 sed 或其...

问题描述:

我想从文件末尾删除n行。可以使用 sed 完成吗?

例如,要删除第 2 到第 4 行,我可以使用

$ sed '2,4d' file

但我不知道行号。我可以使用以下命令删除最后一行

$sed $d file

但我想知道从末尾删除n行的方法。请告诉我如何使用 sed 或其他方法来实现这一点。


解决方案 1:

我不知道sed,但可以这样做head

head -n -2 myfile.txt

解决方案 2:

如果可以选择硬编码 n,则可以对 sed 进行顺序调用。例如,要删除最后三行,请删除最后一行三次:

sed '$d' file | sed '$d' | sed '$d'

解决方案 3:

来自sed 单行命令:

# delete the last 10 lines of a file
sed -e :a -e '$d;N;2,10ba' -e 'P;D'   # method 1
sed -n -e :a -e '1,10!{P;N;D;};N;ba'  # method 2

看起来就是你要找的东西。

解决方案 4:

使用sed,但让 shell 进行计算,目标是d通过给出范围来使用命令(删除最后 23 行):

sed -i "$(($(wc -l < file)-22)),$d" file

要从内到外删除最后 3 行:

$(wc -l < file)

给出文件的行数:比如说2196

我们要删除最后 23 行,因此对于左侧或范围:

$((2196-22))

给出:2174
因此,经过 shell 解释后的原始 sed 是:

sed -i '2174,$d' file

经过-i就地编辑,文件现在有2173行!

如果要将其保存到新文件中,代码为:

sed -i '2174,$d' file > outputfile

解决方案 5:

一个有趣而简单的sed解决tac方案:

n=4
tac file.txt | sed "1,$n{d}" | tac

笔记

  • "shell 需要双引号来评估命令$n中的变量sed。在单引号中,不会执行任何插值。

  • taccat反转的,见man 1 tac

  • in用来分隔& (如果没有, {}shell将尝试插入不存在的变量)sed`$nd$nd`

解决方案 6:

您可以使用头部来完成此操作。

使用

$ head --lines=-N file > new_file

其中 N 是要从文件中删除的行数。

原始文件的内容减去最后 N 行现在位于new_file中

解决方案 7:

为了完整起见,我想添加我的解决方案。我最终按照标准执行了此操作ed

ed -s sometextfile <<< $'-2,$d
wq'

这将使用就地编辑删除最后两行(尽管它确实使用了临时文件/tmp!!)

解决方案 8:

要真正就地截断非常大的文件,我们有truncate命令。它不了解行,但tail+wc可以将行转换为字节:

file=bigone.log
lines=3
truncate -s -$(tail -$lines $file | wc -c) $file

如果文件同时写入,则存在明显的竞争条件。在这种情况下,最好使用head- 它从文件开头计算字节数(注意磁盘 IO),因此我们将始终在行边界处截断(如果文件正在主动写入,则可能比预期的行数更多):

truncate -s $(head -n -$lines $file | wc -c) $file

如果登录尝试失败,可以使用一行代码将密码代替用户名:

truncate -s $(head -n -5 /var/log/secure | wc -c) /var/log/secure

解决方案 9:

这可能对你有用(GNU sed):

sed ':a;$!N;1,4ba;P;$d;D' file

解决方案 10:

上述大多数答案似乎都需要 GNU 命令/扩展:

    $ head -n -2 myfile.txt
    -2: Badly formed number

对于稍微更便携的解决方案:

     perl -ne 'push(@fifo,$_);print shift(@fifo) if @fifo > 10;'

或者

     perl -ne 'push(@buf,$_);END{print @buf[0 ... $#buf-10]}'

或者

     awk '{buf[NR-1]=$0;}END{ for ( i=0; i < (NR-10); i++){ print buf[i];} }'

其中“10”为“n”。

解决方案 11:

通过这里的答案,您已经了解到 sed 不是此应用程序的最佳工具。

但是我确实认为有一种方法可以使用 sed 来实现这一点;这个想法是将 N 行附加到保留空间,直到您能够读取而不会遇到 EOF。当遇到 EOF 时,打印保留空间的内容并退出。

sed -e '$!{N;N;N;N;N;N;H;}' -e x

上面的 sed 命令将省略最后 5 行。

解决方案 12:

可以通过 3 个步骤完成:

a)计算要编辑的文件的行数:

 n=`cat myfile |wc -l`

b) 从该数字中减去要删除的行数:

 x=$((n-3))

c) 告诉 sed 从该行号 ( ) 删除$x到末尾:

 sed "$x,$d" myfile

解决方案 13:

wc -l <file>您可以使用 来获取行数

head -n <total lines - lines to remove> <file>

解决方案 14:

尝试以下命令:

n = line number
tail -r file_name | sed '1,nd' | tail -r

解决方案 15:

这将删除最后 3 行file

for i in $(seq 1 3); do sed -i '$d' file; done;

解决方案 16:

我更喜欢这个解决方案;

head -$(gcalctool -s $(cat file | wc -l)-N) file

其中N是要删除的行数。

解决方案 17:

sed -n ':pre
1,4 {N;b pre
    }
:cycle
$!{P;N;D;b cycle
  }' YourFile

posix 版本

解决方案 18:

删除最后 4 行:

$ nl -b a file | sort -k1,1nr | sed '1, 4 d' | sort -k1,1n | sed 's/^ *[0-9]*    //'   

解决方案 19:

我想到了这个,其中 n 是您要删除的行数:

count=`wc -l file`
lines=`expr "$count" - n`
head -n "$lines" file > temp.txt
mv temp.txt file
rm -f temp.txt

虽然有点绕弯子,但我认为很容易理解。

  1. 计算主文件中的行数

  2. 从计数中减去要删除的行数

  3. 打印出要保留并存储在临时文件中的行数

  4. 用临时文件替换主文件

  5. 删除临时文件

解决方案 20:

#!/bin/sh

echo 'Enter the file name : '
read filename

echo 'Enter the number of lines from the end that needs to be deleted :'
read n

#Subtracting from the line number to get the nth line
m=`expr $n - 1`

# Calculate length of the file
len=`cat $filename|wc -l`

#Calculate the lines that must remain
lennew=`expr $len - $m`

sed "$lennew,$ d" $filename

解决方案 21:

类似于https://stackoverflow.com/a/24298204/1221137的解决方案,但进行了就地编辑,并且没有对行数进行硬编码:

n=4
seq $n | xargs -i sed -i -e '$d' my_file

解决方案 22:

在docker中,这对我有用:

head --lines=-N file_path > file_path

解决方案 23:

假设你有几行:

    $ cat <<EOF > 20lines.txt
> 1
> 2
> 3
[snip]
> 18
> 19
> 20
> EOF

然后你就可以抓住:

# leave last 15 out
$ head -n5 20lines.txt
1
2
3
4
5

# skip first 14
$ tail -n +15 20lines.txt
15
16
17
18
19
20

解决方案 24:

POSIX 兼容解决方案使用ex/ vi,与上述 @Michel 的解决方案类似。@Michel 的ed示例使用“非 POSIX”Here-Strings。增加$-1以删除n到 EOF ($ 的行,或者只输入要删除的行。您可以使用ex来计算行号或执行任何其他 Unix 操作。

给定文件:

cat > sometextfile <<EOF
one
two
three
four
five
EOF

正在执行:

ex -s sometextfile <<'EOF'
$-1,$d
%p
wq!
EOF

返回:

one
two
three

它使用 POSIX Here-Docs,因此修改起来非常容易 - 尤其是set -o vi与 POSIX 一起使用时/bin/sh。说到这个话题,“vim” 的“前个性”应该没问题,但 YMMV。

解决方案 25:

要删除文件的最后 N 行,可以使用相同的概念

$ sed '2,4d' file

您可以使用 tail 命令组合来反转文件:如果 N 是 5

$ tail -r file | sed '1,5d' file | tail -r > file

并且这种方式也可以在head -n -5 file命令无法运行的地方运行(比如在 Mac 上!)。

解决方案 26:

这将删除最后 12 行

sed -n -e :a -e '1,10!{P;N;D;};N;ba'
相关推荐
  政府信创国产化的10大政策解读一、信创国产化的背景与意义信创国产化,即信息技术应用创新国产化,是当前中国信息技术领域的一个重要发展方向。其核心在于通过自主研发和创新,实现信息技术应用的自主可控,减少对外部技术的依赖,并规避潜在的技术制裁和风险。随着全球信息技术竞争的加剧,以及某些国家对中国在科技领域的打压,信创国产化显...
工程项目管理   1565  
  为什么项目管理通常仍然耗时且低效?您是否还在反复更新电子表格、淹没在便利贴中并参加每周更新会议?这确实是耗费时间和精力。借助软件工具的帮助,您可以一目了然地全面了解您的项目。如今,国内外有足够多优秀的项目管理软件可以帮助您掌控每个项目。什么是项目管理软件?项目管理软件是广泛行业用于项目规划、资源分配和调度的软件。它使项...
项目管理软件   1354  
  信创国产芯片作为信息技术创新的核心领域,对于推动国家自主可控生态建设具有至关重要的意义。在全球科技竞争日益激烈的背景下,实现信息技术的自主可控,摆脱对国外技术的依赖,已成为保障国家信息安全和产业可持续发展的关键。国产芯片作为信创产业的基石,其发展水平直接影响着整个信创生态的构建与完善。通过不断提升国产芯片的技术实力、产...
国产信创系统   21  
  信创生态建设旨在实现信息技术领域的自主创新和安全可控,涵盖了从硬件到软件的全产业链。随着数字化转型的加速,信创生态建设的重要性日益凸显,它不仅关乎国家的信息安全,更是推动产业升级和经济高质量发展的关键力量。然而,在推进信创生态建设的过程中,面临着诸多复杂且严峻的挑战,需要深入剖析并寻找切实可行的解决方案。技术创新难题技...
信创操作系统   27  
  信创产业作为国家信息技术创新发展的重要领域,对于保障国家信息安全、推动产业升级具有关键意义。而国产芯片作为信创产业的核心基石,其研发进展备受关注。在信创国产芯片的研发征程中,面临着诸多复杂且艰巨的难点,这些难点犹如一道道关卡,阻碍着国产芯片的快速发展。然而,科研人员和相关企业并未退缩,积极探索并提出了一系列切实可行的解...
国产化替代产品目录   28  
热门文章
项目管理软件有哪些?
云禅道AD
禅道项目管理软件

云端的项目管理软件

尊享禅道项目软件收费版功能

无需维护,随时随地协同办公

内置subversion和git源码管理

每天备份,随时转为私有部署

免费试用