我在zsh上创建了一个空目录并添加了一个文件 通过执行以下操作调用hello.rb:
echo 'Hello, world.' >hello.rb
如果我想使用终端在此文件中进行更改 在不打开文件的情况下执行此操作的正确方法是什么 本身用let说的TextEditor?
我希望能够严格对文件hello.rb
进行更改
通过使用我的zsh终端,这是可能的吗?
答案 0 :(得分:3)
Zsh不是终端而是shell。终端是shell执行的窗口。 shell是文本程序,提示您执行命令并执行它们。
如果要在终端中编辑文件,则使用vim
,nano
,emacs -nw
或任何其他文本模式文本编辑器即可。它们不是Zsh命令,而是可以从Zsh或任何其他shell调用的外部命令。
如果要在Zsh中编辑文件,请使用zed
。您需要运行一次(~/.zshrc
)
autoload zed
然后您可以使用
编辑hello.rb
zed hello.rb
(退出并使用Control-j
保存)
答案 1 :(得分:1)
Zed是一个很好的答案,但是为了更加精简 - 对于即使是脚本也可以进行的编辑级别 - zsh可以将所有256个字符/字节值(包括null)传递给变量。这意味着您可以直接从命令行逐行或几乎任何类型的文件数据进行编辑。这大约是zed / vared所做的。如果您的当前版本包含所有标准模块,则加载zsh/mapfile
或zsh/system
是一个很大的好处,这样您就可以捕获命令扩展遗漏的任何字符( zed使用$(<$file)
将文件读取到内存中。以下是您可以使用此变量操作方法的示例:
% typeset -T Buffer buffer $'\n'
% typeset -T Edit edit $'\n'
最常用的是使用换行符来划分想要编辑的文本文件。 这个方便的功能将使zsh一次完全访问一行或一系列行,而不会无意中弄乱数据。
% zmodload zsh/mapfile
% Buffer=$mapfile[path/to/file]
这里,我使用方便的mapfile
模块,因为我可以逐字节加载文件的内容。或者你可以使用% Buffer="$(<path/to/file)"
,就像zed一样,但你总是会删除尾随的换行符,并且可能会出现错字或环境变化的其他单词拆分,因此模块方法的简单性是最好的。完成后,只需将$Buffer
值分配回$mapfile[file]
或使用更经典的命令printf '%s' $Buffer >path/to/file
来保存更改(这是精确的字符串写入,逐字节,所以你写的任何新行或格式都会被写入。
您可以使用映射的数组在Buffer和Edit之间传输行,但请记住,在最简单的形式中,将一个数组分配给另一个完全为空的drop元素(one \n \n two \n three
变为one \n two \n three
) 。您可以通过引用输入数组并添加&#39; @&#39;来抑制此空元素删除。符号到其索引"$buffer[@]"
,如果使用整个数组;并添加&#39; @&#39;如果使用数组"${(@)buffer[2,50]}"
的范围,则为该标志的符号。保留空行对于键入来说可能有点麻烦,但是这些多个数组只能在脚本或函数中使用,因为您可以使用buffer[54]="echo This is a newly written line."
% edit=($buffer[50,70])
...
% buffer[50,70]=($edit)
这是标准的Zsh语法,这意味着在...
区域中您可以编辑和操作$edit
行数组或$Edit
标量文本块,包括添加多行或带走一些。当您将这些行添加回$buffer
时,它将用新行替换指定的行块(50-70),自动扩展或缩小其他数组元素以容纳重新整合的行。 - 由于动态数组调整,您还可以插入任何需要的内容,如buffer[40]=("new string as new line" "$buffer[40]")
这样的新行。这会在给定索引之前插入它,而交换元素("$buffer[40]" "new string as new line")
的顺序会在给定索引后插入新行。要么将所有后续元素(包括完全空元素)调整为当前索引加一。
如果您想重新编写zed
函数,以某种复杂的方式使用此方法,例如:newzed /path/to/file [start-line] [end-line]
,那将非常棒且方便。
在我离开之前,我想提一下,直接使用vared
,一旦您在交互式终端上输入了这些命令,您可能会觉得令人沮丧的是您无法使用&#34;输入&# 34;用于插入或追加新行。我发现使用我的终端和使用ESC-ENTER的Zsh版本运行良好,但我不知道旧版本(如果我的记忆是正确的话,Mac通常会出现一个不是最新版本的版本)。如果这不起作用,您可能需要进行一些文档挖掘以了解如何设置ZLE(Zsh行编辑器,Zsh的一个组件)或获取更新版本的Zsh。此外,一些其他shell,当索引标量变量时可以按字节计数,因为在ascii和C中一个字节与一个字符相同,但是Zsh支持UTF8并且将通过UTF8字符索引标量字符串,除非你关闭shell选项multibyte
(默认情况下已启用)。如果您需要使用旧的字节字符索引,这将有助于操作每一行。此外,如果你有一个版本的Zsh,对于未使用zsh/mapfile
或zsh/system
编译的任何内容,那么你可以使用read
内置的多个选项来实现类似的效果,例如{ {1}}。正如您在此处所看到的,您必须使读取长度足够大以容纳文件的大小,否则它将不会占用文件的一部分,并且<path/to/file |read -u 0 -k $[5 * 2**20] -r -s Buffer ||(($#Buffer))
返回代码几乎总是错误,因为无法读取字符串的全长。我们用read
解决了这个问题,但是这个内置函数根本不是为了有效地处理大规模字节操作,所以你看到的就是你可以从中得到的东西。