vim 嵌套单行循环中断命令
vim nested one-liner loop breaks command
我想为文件中的特定行多次附加一个字符,这样所有行都会有 x 个字符
假设我希望 20 到 80 之间的所有行具有相同数量的字符 (50) 并且在末尾附加相同的字符:
for y in range(20, 80) | if strlen(getline(y)) !=50 | for i in range(50-strlen(getline(y))) | execute y .. 's/$/./' | endfor | endif | endfor
returns
E727:Start past end
和 E1098: String, List or Blob required
如果我将它与特定的行一起使用,它就可以正常工作
if strlen(getline(N)) !=50 | for i in range(50-strlen(getline(N))) | execute N .. 's/$/./' | endfor | endif
例如:
输入:
abcdef
defghijklm
foo
输出:
abcdef**********
defghijklm******
foo*************
使用 GNU sed。先追加16颗星,然后只保留前16个字符。
sed -E 's/$/****************/; s/(.{16}).*//' file
输出:
abcdef**********
defghijklm******
foo*************
这些错误从何而来?
E727: Start past end
此错误是由range(50-strlen(getline(y)))
中的公式50-strlen(getline(y))
引起的,当y
行的字符数超过50时,returns为负数:help range()
不喜欢。
E1098: String, List or Blob required
此错误是前一个错误的结果:range(50-strlen(getline(y)))
returns 没有任何内容可以循环,因此 :for
无法工作。
这些错误可能可以通过向您的“一个班轮”添加更多检查和分支来避免,但这似乎不是一个好主意,因为您的命令对于它所做的一点点来说已经太复杂了。
期望的结果可以通过更简单的方法更可靠地实现:
:20,80s/$/\=repeat('*',50-strlen(getline('.')))
- 这是一个快速
:help :substitute
,带有范围、模式和 :help sub-replace-special
表达式。
20,80
是我们的范围,见:help :range
.
$
是我们的零宽度图案,行尾。
- 非常强大的
\=<expr>
允许我们使用<expr>
返回的字符串作为替换。
:help repeat()
将给定的字符串重复给定的次数。
*
是我们的字符串。
- 重复次数是用你自己的公式计算出来的。当行长于50时,重复次数为负数,表示没有重复,因此不会在行后附加
*
。
之前:
a short line
some filler text foo
a line with 59 characters dgsfdsjgdfsjdshdlsjdfshjdsfdlhsjd
what
之后:
a short line**************************************
some filler text foo******************************
a line with 59 characters dgsfdsjgdfsjdshdlsjdfshjdsfdlhsjd
what**********************************************
只需使用 awk,它是为这样的工作而创建的:
$ cat file
line 1
line 2
line 3
abcdef
defghijklm
foo
line 7
line 8
$ awk '
BEGIN { wid=50; pad=sprintf("%*s",wid,""); gsub(/ /,"*",pad) }
4<=NR && NR<=6 { [=11=]=substr([=11=] pad,1,wid) }
1' file
line 1
line 2
line 3
abcdef********************************************
defghijklm****************************************
foo***********************************************
line 7
line 8
更改宽度(以上 50)和 start/end 行号(以上 4 和 6)以适应。
我想为文件中的特定行多次附加一个字符,这样所有行都会有 x 个字符
假设我希望 20 到 80 之间的所有行具有相同数量的字符 (50) 并且在末尾附加相同的字符:
for y in range(20, 80) | if strlen(getline(y)) !=50 | for i in range(50-strlen(getline(y))) | execute y .. 's/$/./' | endfor | endif | endfor
returns
E727:Start past end
和 E1098: String, List or Blob required
如果我将它与特定的行一起使用,它就可以正常工作
if strlen(getline(N)) !=50 | for i in range(50-strlen(getline(N))) | execute N .. 's/$/./' | endfor | endif
例如:
输入:
abcdef
defghijklm
foo
输出:
abcdef**********
defghijklm******
foo*************
使用 GNU sed。先追加16颗星,然后只保留前16个字符。
sed -E 's/$/****************/; s/(.{16}).*//' file
输出:
abcdef********** defghijklm****** foo*************
这些错误从何而来?
E727: Start past end
此错误是由
range(50-strlen(getline(y)))
中的公式50-strlen(getline(y))
引起的,当y
行的字符数超过50时,returns为负数:help range()
不喜欢。E1098: String, List or Blob required
此错误是前一个错误的结果:
range(50-strlen(getline(y)))
returns 没有任何内容可以循环,因此:for
无法工作。
这些错误可能可以通过向您的“一个班轮”添加更多检查和分支来避免,但这似乎不是一个好主意,因为您的命令对于它所做的一点点来说已经太复杂了。
期望的结果可以通过更简单的方法更可靠地实现:
:20,80s/$/\=repeat('*',50-strlen(getline('.')))
- 这是一个快速
:help :substitute
,带有范围、模式和:help sub-replace-special
表达式。 20,80
是我们的范围,见:help :range
.$
是我们的零宽度图案,行尾。- 非常强大的
\=<expr>
允许我们使用<expr>
返回的字符串作为替换。 :help repeat()
将给定的字符串重复给定的次数。*
是我们的字符串。- 重复次数是用你自己的公式计算出来的。当行长于50时,重复次数为负数,表示没有重复,因此不会在行后附加
*
。
之前:
a short line
some filler text foo
a line with 59 characters dgsfdsjgdfsjdshdlsjdfshjdsfdlhsjd
what
之后:
a short line**************************************
some filler text foo******************************
a line with 59 characters dgsfdsjgdfsjdshdlsjdfshjdsfdlhsjd
what**********************************************
只需使用 awk,它是为这样的工作而创建的:
$ cat file
line 1
line 2
line 3
abcdef
defghijklm
foo
line 7
line 8
$ awk '
BEGIN { wid=50; pad=sprintf("%*s",wid,""); gsub(/ /,"*",pad) }
4<=NR && NR<=6 { [=11=]=substr([=11=] pad,1,wid) }
1' file
line 1
line 2
line 3
abcdef********************************************
defghijklm****************************************
foo***********************************************
line 7
line 8
更改宽度(以上 50)和 start/end 行号(以上 4 和 6)以适应。