我有以一个或多个换行符结尾的文件,并且应该只以一个换行符结尾。我如何使用 Bash/Unix/GNU 工具做到这一点?
坏文件示例:
1\n
\n
2\n
\n
\n
3\n
\n
\n
\n
Run Code Online (Sandbox Code Playgroud)
示例更正文件:
1\n
\n
2\n
\n
\n
3\n
Run Code Online (Sandbox Code Playgroud)
换句话说:在 EOF 和文件的最后一个非换行符之间应该只有一个换行符。
读取文件内容,切掉一个换行符,直到最后没有另外两个换行符,写回:
#! /bin/python
import sys
with open(sys.argv[1]) as infile:
lines = infile.read()
while lines.endswith("\n\n"):
lines = lines[:-1]
with open(sys.argv[2], 'w') as outfile:
for line in lines:
outfile.write(line)
Run Code Online (Sandbox Code Playgroud)
澄清:当然,管道是允许的,如果这样更优雅的话。
该程序ed是一个最小的文本编辑器,不能通过使用Ctrl-向它发送中断来退出C,而是打印错误消息“?” 到控制台。为什么ed在收到中断时不直接退出?当然,没有理由为什么一个神秘的错误消息在这里比退出更有用。这种行为导致许多新用户进入以下类型的交互:
Run Code Online (Sandbox Code Playgroud)$ ed hello ? help ? exit ? quit ? ^C ? ^C ? ? ? ^D $ su # rm -f /bin/ed
如此悲惨的浪费——如果ed只是同意被打断,就很容易避免。
另一个表现出类似行为的顽固程序less似乎也没有太多理由忽略C-c. 为什么这些程序不只是提示?
由于尚未诊断的应用程序错误,我有数百个磁盘已满的服务器。有一个文件被重复的行填满——不是日志文件,而是一个带有变量定义的用户环境文件(所以我不能直接删除该文件)。
我编写了一个简单的sed命令来检查错误添加的行并删除它们,并在文件的本地副本上对其进行了测试。它按预期工作。
但是,当我在带有完整磁盘的服务器上尝试它时,我得到了大约以下错误(它来自内存,而不是复制和粘贴):
sed: couldn't flush /path/to/file/sed8923ABC: No space left on deviceServerHostname
Run Code Online (Sandbox Code Playgroud)
当然,我知道没有剩余空间了。这就是为什么我试图删除东西!(sed我使用的命令会将 4000 多行的文件减少到大约 90 行。)
我的sed命令只是sed -i '/myregex/d' /path/to/file/filename
尽管磁盘已满,有没有办法可以应用此命令?
(它必须是自动化的,因为我需要将它应用到数百台服务器上作为快速修复。)
(显然需要诊断应用程序错误,但同时服务器无法正常工作......)
更新:通过删除我发现可以删除的其他内容来解决我面临的情况,但我仍然希望得到这个问题的答案,这对未来和其他人都有帮助。
/tmp是不行的;它在同一个文件系统上。
在释放磁盘空间之前,我进行了测试,发现可以vi通过打开文件并运行来删除其中的行:g/myregex/d,然后使用:wq. 似乎应该可以自动执行此操作,而无需求助于单独的文件系统来保存临时文件......(?)
我认为可能是qed,但我找不到任何来源来证实或否认这一点。
此外,ed它存在于 Unix 的整个时期,并sam于 1980 年代初编写。是否知道从 Unix 时代到 Plan9 的贝尔实验室大多数人使用的是什么?
我在想时间线是这样的:
qed-> ed-> sam->acme
获取以下文件:
$ cat f1
stu vwx yza
uvw xyz abc
abc def ghi
def ghi jkl
ghi jkl mno
jkl mno pqr
mno pqr stu
pqr stu vwx
stu vwx yza
Run Code Online (Sandbox Code Playgroud)
要打印从包含GNU的第一行abc到包含GNU 的第一行的所有行:mnosed
$ sed -n '/abc/,/mno/p' f1
uvw xyz abc
abc def ghi
def ghi jkl
ghi jkl mno
Run Code Online (Sandbox Code Playgroud)
我怎样才能打印所有行,直到最后一行包含mno,例如我怎样才能得到以下结果:
uvw xyz abc
abc def ghi
def ghi jkl
ghi jkl mno
jkl mno pqr
mno pqr stu
Run Code Online (Sandbox Code Playgroud)
换句话说,有没有办法让GNU …
我想知道ed编辑器对于交互式编辑是否不再有用。我知道该diff命令可以将补丁作为ed脚本生成,这ed是波特率超慢时的最后手段。但是还有其他学习和使用的理由ed吗?
在 Ed 中,我可以进行搜索以替换所有空行,如下所示:
g/^$/d
Run Code Online (Sandbox Code Playgroud)
这将删除所有空行。但是如果我想删除两个或更多空行并保留 1 怎么办?例如:
Line 1
Line 2
Line 3
Run Code Online (Sandbox Code Playgroud)
变成:
Line 1
Line 2
Line 3
Run Code Online (Sandbox Code Playgroud) 该g选项(例如s/pattern/replacement/g对于许多工具使用正则表达式风格的模式匹配和):g的命令ed,ex,vi,并vim有相当类似的使用和意义:匹配给定的正则表达式“全球”,即第一比赛结束后不停止。
我对此有两个问题:
:g命令还是g模式匹配标志,在哪个工具中?看起来大多数在模式匹配中sed使用g标志的工具(例如)实际上只是直接或间接模拟ed。例如,在后 Perl 时代,大多数使用正则表达式的工具都允许g标记,因为 Perl允许,而 Perl 会出现,因为ed-> sed-> Perl。因此,如果答案是“它们是在原始ed工具中同时引入的,并且除此之外没有历史先例”,我也不会感到惊讶。global选项(或命令)?它真的没有什么“全球性”的;该:g命令与任何其他ed命令一样采用一系列行,并且该g标志不会以任何方式扩展搜索范围(它只允许多次点击)。我想我想不出更好的名字,但所选的名字对我来说似乎很奇怪,所以我想知道是否有一些我没有看到的原因。我有大量文件需要减小大小。我发现大多数(不是全部)文件都有一个结束部分,可以在不丢失信息的情况下进行剪切:
Data 1
Data 2
something_unimportant_here END DATA
Rubbish 1
Rubbish 2
Run Code Online (Sandbox Code Playgroud)
如何通过删除包括“END DATA”在内的行和所有后续行,就地,仅更改包含该模式的文件,从而最大限度地减少对磁盘的写访问(许多,许多)来编辑文件(因此,全部)文件和慢速磁盘)。
如果可能,我想在文件中添加一个新的最后一行(我自己的结束标记),以便文件的语法保持正确——同样,仅在包含该模式的文件中。
我正在考虑使用ed,比如
echo ',s/END DATA/ ???? '\\n'q'\\n'wq' | ed "$file"
Run Code Online (Sandbox Code Playgroud)
但似乎无法管理???部分更正。
预期输出:
Data 1
Data 2
NEW END
Run Code Online (Sandbox Code Playgroud)