J
及其几个变体(gJ
等)在Vim中加入行; J
将“删除缩进并最多插入两个空格”。但是还有直接插入另一个字符而不是两个空格的简单方法吗?例如逗号(
,
)或逗号和空格(,
)吗?给出:
8
9
10
32
我想结束:
8, 9, 10, 32
或:
8,9,10,32
#1 楼
我写了一个Join插件,可以做您想做的事情,还有很多事情。带分隔符的连接线(字符串)
有或没有修剪前/后空格的连接线
负数连接线(向后连接)
>反向连接线
连接线并保持连接线(不删除连接线)
使用以上选项的任意组合连接线
更多详细信息和屏幕截图:
https://github.com/sk1418/Join
#2 楼
一种简单的方法是:只需选择您的行(除最后一行以外的所有行)-或使用%
-并运行: > :'<,'>s/\n/,/
(当然,其中Vim在
'<,'>
之后已经插入了:
部分,以定位选择) br /> 在上面的内容(以及Sato Katsura的评论)的基础上,这是一个可能的“交互式联接”实现,具有计数和可选的重复支持:
:'<,'>s/\n/, /
>和实际的映射:" ================ script ===============================================
" interactive 'J', 'gJ' replacement with optional 'vim-repeat' support
" The last used separator is automatically reused as:
" a. default choice
" b. when repeating (=> non-interactive repeats: same range, same separator)
let g:last_join_separator = " "
function! s:interactiveJoin(use_last_sep,...) range
if (a:use_last_sep == 0) "interactive, ask for separator to use
call inputsave()
echohl Question
let l:sep = input("Separator:", g:last_join_separator)
echohl None
call inputrestore()
redraw!
let g:last_join_separator = l:sep "update last separator value
else "non-interactive (when repeating with '.')
let l:sep = g:last_join_separator
endif
if (a:0 == 0) "with no argument, remove indentation *and trailing spaces*
let l:subst = 's/\s*\n\+\s*/\=' . "'" . l:sep . "'/"
else " don't remove indentation or trailing spaces (act like 'gJ')
let l:subst = 's/\n\+/\=' . "'" . l:sep . "'/"
endif
if a:firstline < a:lastline "join given range
execute a:firstline . ',' . (a:lastline - 1) . l:subst
let l:count = a:lastline - a:firstline + 1 "default count for repeat
else "or join only with next line
execute l:subst
let l:count = 1 "default count for repeat
endif
"make command repeatable
"(with the tpope/vim-repeat plugin: optional, recommended)
if (a:0 == 0)
silent! call repeat#set("\<Plug>(repeatJoin)", l:count)
else
silent! call repeat#set("\<Plug>(repeatGJoin)", l:count)
endif
endfunction
noremap <silent> <Plug>(interactiveJoin) :call <SID>interactiveJoin(0)<CR>
noremap <silent> <Plug>(interactiveGJoin) :call <SID>interactiveJoin(0,'g')<CR>
noremap <silent> <Plug>(repeatJoin) :call <SID>interactiveJoin(1)<CR>
noremap <silent> <Plug>(repeatGJoin) :call <SID>interactiveJoin(1,'g')<CR>
这有点像
J
,但是是交互式的-它会提示输入分隔符字符串。默认字符串是空格-例如,要连接不带分隔符的行,请在提示时按Backspace
,删除默认的空格字符,然后按Enter
接受(现在)空分隔符。计数,例如3J
,也可以。如果安装了tpope/vim-repeat
插件,则以“。”重复。也可以使用,重新使用最后一个分隔符和(如果未更改,例如10.
)最后一个计数或可视行范围。(*)它与
J
并不完全相同,尽管:虽然会删除缩进,它不会检查.!?
(词尾)是插入2个空格而不是一个空格,或者仅在缺少空格时才插入空格(很难做这样的事情,因为分隔符字符串现在可以是任何东西) 。它还会删除尾随空格(更有意义)。不是一个运算符,但是接近一个运算符-例如,您不能执行J
来加入“一个单词”。(欢迎提出建议)
评论
更好的是::'<,'>-1s / \ n /,/用于标记行,或:1,$-1s / \ n /,/对于整个文件。
–佐藤桂
2015年8月3日在8:33
确实,这甚至更好:)
– VanLaser
15年8月3日在8:35
@SatoKatsura你能解释-1吗?
– alxndr
15年8月3日在18:12
@alxndr-用于跳过范围/文件中的最后一行:例如在OP示例中,您不希望逗号在32之后,并且也不想将其与下一行连接(如果存在)。您甚至可以使用'<,'>-s / \ n /,/或1,$-s / \ n /,/--与-1相同。
– VanLaser
15年8月3日在20:41
如果l:sep是&,则替换将无法正常工作,因为&是替换中的魔术。最好使用\ =来使用文字字符串-让l:subst ='s / \ n \ + / \ ='。 “”。 l:sep “'/”-而不是尝试转义。
–詹姆斯
2015年8月5日在20:29
#3 楼
这是使用外部命令的示例::%!paste -sd,
其中
%!
用以下命令替换当前缓冲区(文件的内容):paste -sd,
(参数-s
用于连接多行和-d
将分隔符设置为,
)。#4 楼
以防万一有人不喜欢输入正则表达式并记住更多的Plugin Ex命令:Visual-block Append
Visual-block Append在Visual Block模式下可用(
<C-v>
),并可以执行一个块追加(和块插入作为前置)。 (ref::help v_b_A
,:help v_b_I
)如果“块可视模式”中的最后一个动作是
$
,则追加将在所有选择的结尾处完成;否则将在您添加的文本之前插入空格(可以想象在代码中几个方法调用的末尾对齐闭包)
)。下面带有示例文本,并将光标放在
8
上: /> 8
9
10
12
<C-v>}$A,<C-c>
。回到正常模式后,我们可以看到,
被附加到所有选定的行。 (尝试不使用$
)然后执行
gv
重新选择区域和J
或gJ
。我们已经完成了结尾,
:8,9,10,12,
和$x
的操作已经完成。花哨的,
),然后尝试使用Visual Insert:uu..u
,然后我们可以使用:ea 1d<cr>:lat 1
将行加入空格。等待,等待,缺少某些内容。如何重新选择整个“数组”?这次我们没有选择第一行...所以
j<C-v>}I, <C-c>
无济于事。 。PS我的小指不够快速且不够准确,无法为
gJ
输入gv
,因此我喜欢结合使用Vim内置的操作和动作来避免使用正则表达式。但是,如果我经常这样做,请使用映射-也许映射到插件的映射应该更好。#5 楼
您可以记录宏以逗号分隔行。如果这是一项罕见的任务或一次性任务,这很有用,并且您不记得如何编写替代命令和正则表达式来执行任务,但是您确实记得如何记录和运行宏。 br />要用逗号连接行,请键入qjgJi,Escq将宏记录在寄存器j
中。然后,您可以使用@j运行宏。您可以使用@@重新运行该宏,这样可以节省连续运行多次时的键入次数,甚至可以按住@直到到达要加入的行的末尾。您还可以在@j或@@上使用数字前缀将其重复设定的次数。这将保留前导和尾随空格,因此,如果您的原始文本中有空格,则在逗号之前或之后会有空格。要加入逗号和空格,请在,和Esc之间插入空格录制宏时。
录制宏时,也可以使用J而不是gJ,通常会用逗号和空格连接行。但是,如果当前行具有尾随空格,则逗号将出现在空格之后,后面没有空格。另外,如果下一行以
)
开头,则不包含空格;如果设置了joinspaces
且当前行以.
,!
或?
结尾,则它在逗号后放置两个空格。这些警告在:help J
下进行了描述。#6 楼
一种无需插件或外部命令即可将空格(J
)从空间重新映射到所需字符的简单得多的方法。例如,要用逗号和空格连接::nmap J :s/\n/, /^M
对于末尾的特殊字符换行符(
^M
),请按Ctrl-V
,然后按Return / Enter。如果要替换为制表符(^I
),请键入Ctrl-I
,然后键入Tab
,同样如此。行并将该行为重新映射到J字符。这也可以与组合一起使用,如
4J
中所示,以连接下4行。#7 楼
为了解决此限制,我们可以通过将其拆分为两个单独的简单问题来解决此问题: />:%s/$/,/
-:%s
搜索整个文件,并用逗号($
)替换每行(,
):%norm A,
-对于文件中的每一行,请执行以下命令A,
(附加,
) br />在行尾添加子字符串的更多方法用
%join
连接行此解决方案是比
%s/\n/,/
更容易提出。评论
欢迎来到Vi和Vim!我喜欢您使用惯用语;这是一种快速而灵活的方法。我也喜欢$而不是\ n-并非所有文件都将\ n用作eol,因此实际上比:%substitute / \ n /,好!
– D. Ben Knoble♦
20-11-30在17:02
评论
您还可能喜欢github.com/sk1418/Join(未经测试)。所有这些答案都是无用的。请立即访问unix.stackexchange.com/a/338124/107860,以获得即时答案。
@lobi不是Vim吗?此外,sed与:%s /../../?
大致相同