如何使用 sed 删除文件的最后 n 行
- 2024-10-25 08:42:00
- admin 原创
- 90
问题描述:
我想从文件末尾删除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
。在单引号中,不会执行任何插值。tac
是cat
反转的,见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
虽然有点绕弯子,但我认为很容易理解。
计算主文件中的行数
从计数中减去要删除的行数
打印出要保留并存储在临时文件中的行数
用临时文件替换主文件
删除临时文件
解决方案 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'
- 2024年20款好用的项目管理软件推荐,项目管理提效的20个工具和技巧
- 2024年开源项目管理软件有哪些?推荐5款好用的项目管理工具
- 项目管理软件有哪些?推荐7款超好用的项目管理工具
- 项目管理软件哪个最好用?盘点推荐5款好用的项目管理工具
- 项目管理软件有哪些最好用?推荐6款好用的项目管理工具
- 2024年常用的项目管理软件有哪些?推荐这10款国内外好用的项目管理工具
- 项目管理软件有哪些,盘点推荐国内外超好用的7款项目管理工具
- 2024项目管理软件排行榜(10类常用的项目管理工具全推荐)
- 项目管理软件排行榜:2024年项目经理必备5款开源项目管理软件汇总
- 项目管理必备:盘点2024年13款好用的项目管理软件