给出文件的行数:比如说2196
我们想删除最后23行,所以对于左侧或范围:
$((2196-22))
给:2174
因此,shell解释后的原始sed是:
sed -i '2174,$d' file
使用-i进行就地编辑,文件现在是2173行!
如果要将其保存到新文件中,代码为:
sed -i '2174,$d' file > outputfile
你可以用头来做这个。
使用
$ head --lines=-N file > new_file
其中N是您要从文件中删除的行数。
原始文件的内容减去最后N行现在在new_file中
--lines不适用于osx
为了完整起见,我想补充一下我的解决方案。
我最终使用标准ed执行此操作:
ed -s sometextfile <<<$&#39;-2,$d
wq&#39;
这将使用就地编辑删除最后两行(尽管它确实使用/tmp中的临时文件!!)
要真正就地截断非常大的文件&#xff0c;我们有truncate命令。
它不知道行&#xff0c;但tail &#43; wc可以将行转换为字节&#xff1a;
file&#61;bigone.log
lines&#61;3
truncate -s -$(tail -$lines $file | wc -c) $file
如果文件同时写入&#xff0c;则存在明显的竞争条件。
在这种情况下&#xff0c;最好使用head - 它从文件开头(思维磁盘IO)计算字节数&#xff0c;因此我们将始终截断行边界(如果文件被主动写入&#xff0c;可能会比预期更多行)&#xff1a;
truncate -s $(head -n -$lines $file | wc -c) $file
如果您失败登录尝试将密码替换为用户名&#xff0c;则方便一行&#xff1a;
truncate -s $(head -n -5 /var/log/secure | wc -c) /var/log/secure
这可能适合你(GNU sed)&#xff1a;
sed &#39;:a;$!N;1,4ba;P;$d;D&#39; file
尼斯。你错过了结尾的撇号(&#39;)。
&#64;Thor哎呀&#xff01;感谢您指出了这一点。
对于这么晚的评论感到抱歉&#xff0c;但我尝试(并为我的AIX / posix加上)它打印除了最后一行之外都失败了。读取代码&#xff0c;我不明白最后四行是如何被删除的&#xff0c;显式循环是在第一行的4行&#xff0c;因此它肯定在GNU sed的d&#xff0c;d或P之后循环&#xff0c;而不是在posix版本上。在d之后似乎没有打印行&#xff0c;并且在没有传递到动作行的"结束"的情况下保留在新循环的工作缓冲区中。
&#64;NeronLeVelu程序在一个4行的窗口中读入模式空间&#xff0c;然后附加下一行并打印第一行&#xff0c;直到它到达文件末尾&#xff0c;删除剩余的行。
&#64;potong是的&#xff0c;我在GNU sed上进行测试&#xff0c;它在缓冲区之间保持缓冲区&#xff0c;其中posix在d之后卸载它&#xff0c;产生相反的效果。
上面的大多数答案似乎都需要GNU命令/扩展&#xff1a;
$ head -n -2 myfile.txt
-2: Badly formed number
对于更轻松的解决方案&#xff1a;
perl -ne &#39;push(&#64;fifo,$_);print shift(&#64;fifo) if &#64;fifo > 10;&#39;
要么
perl -ne &#39;push(&#64;buf,$_);END{print &#64;buf[0 ... $#buf-10]}&#39;
要么
awk &#39;{buf[NR-1]&#61;$0;}END{ for ( i&#61;0; i <(NR-10); i&#43;&#43;){ print buf[i];} }&#39;
其中"10"是"n"。
它可以分3个步骤完成&#xff1a;
a)计算要编辑的文件中的行数&#xff1a;
n&#61;&#96;cat myfile |wc -l&#96;
b)从该数字中减去要删除的行数&#xff1a;
x&#61;$((n-3))
c)告诉sed从该行号($x)删除到结尾&#xff1a;
sed"$x,\$d" myfile
数学不好。 如果你必须删除3行&#xff0c;则减去3但是加1。用数学计算&#xff0c;如果文件有10行&#xff0c;10 - 3 &#61; 7而你使用sed删除7到10行&#xff0c;那就是4行&#xff0c;不是3。
通过这里的答案&#xff0c;您已经了解到sed不是此应用程序的最佳工具。
但是我确实认为使用sed有一种方法可以做到这一点;我的想法是附加N行来保持空间&#xff0c;直到你能够阅读而不会击中EOF。点击EOF时&#xff0c;打印保留空间的内容并退出。
sed -e &#39;$!{N;N;N;N;N;N;H;}&#39; -e x
上面的sed命令将省略最后5行。
在这里不起作用
请尝试以下命令&#xff1a;
n &#61; line number
tail -r file_name | sed &#39;1,nd&#39; | tail -r
请解释这是如何工作的。仅供参考 - 要初始化shell变量&#xff0c;我们不应该在&#61;周围有空格。
&#64;codeforester第一行是我猜的评论。他只使用tail -r&#xff0c;其他人使用tac来反转行顺序&#xff0c;并使最后的n行成为n的第一行。
您可以使用wc -l获取行的总计数
head -n
我更喜欢这个解决方案
head -$(gcalctool -s $(cat file | wc -l)-N) file
其中N是要删除的行数。
sed -n &#39;:pre
1,4 {N;b pre
}
:cycle
$!{P;N;D;b cycle
}&#39; YourFile
posix版本
要删除文件的最后N行&#xff0c;可以使用相同的概念
$sed &#39;2,4d&#39; file
您可以使用带有tail命令的组合来反转文件&#xff1a;如果N是5
$tail -r file | sed &#39;1,5d&#39; file | tail -r > file
这种方式也运行head -n -5 file命令不运行(就像在Mac上&#xff01;)。
我想出了这个&#xff0c;其中n是你想要删除的行数&#xff1a;
count&#61;&#96;wc -l file&#96;
lines&#61;&#96;expr"$count" - n&#96;
head -n"$lines" file > temp.txt
mv temp.txt file
rm -f temp.txt
这是一个小迂回&#xff0c;但我认为很容易遵循。
计算主文件中的行数
减去要从计数中删除的行数
打印出要保留的行数并存储在临时文件中
用temp文件替换主文件
删除临时文件
这将删除file中的最后3行&#xff1a;
for i in $(seq 1 3); do sed -i &#39;$d&#39; file; done;
这对于大文件来说太昂贵了 - 整个文件必须被读取和重写n次&#xff01;和sed一样多的叉子。
这将删除最后12行
sed -n -e :a -e &#39;1,10!{P;N;D;};N;ba&#39;
要删除最后4行&#xff1a;
$nl -b a file | sort -k1,1nr | sed &#39;1, 4 d&#39; | sort -k1,1n | sed &#39;s/^ *[0-9]*\t//&#39;
请解释您的陈述如何运作。
与头部相比&#xff0c;有点沉重(特别是在资源方面)。至少tac file | sed &#39;1,4d&#39; | tac因为排序然后删除前缀成本很多的资源。
&#64;NeronLeVelu你是对的但是没有tac命令是某些系统(例如FreeBSD&#xff1f;)