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 endE1098: 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)以适应。