例如,如果我有一行从头开始,并且需要它与前一行对齐,我该如何最有效地做到这一点。
preceeding line
line I need to add spaces to
所以它看起来像这样:
predeeding line
where it needs to start.
它与需要开始的位置正好相距 8 个空格。我该如何使用 vim、awk 或 sed 或其他工具来做到这一点?
其他要求/注意事项:
这些行在我的文件中出现多次,我只想在第 100 行到第 500 行之间进行更改。
答案1
让我们考虑这个测试文件:
$ cat file1
preceeding line
line I need to add spaces to
preceeding line
preceeding line
line I need to add spaces to
下面将非缩进的行缩进以匹配上一行的缩进:
$ awk '{if (/^[^ \t]/) $0=x $0; else {x=$0; sub(/[^ \t].*/, "", x);}} 1' file1
preceeding line
line I need to add spaces to
preceeding line
preceeding line
line I need to add spaces to
怎么运行的
if (/^[^ \t]/) $0=x $0; else {x=$0; sub(/[^ \t].*/, "", x);}
如果行首既不是空格也不是制表符,则将缩进添加
x
到行首。否则,将当前行的缩进保存在变量中
x
。1
这是 awk 中 print-the-line 的神秘简写。
多行版本
对于那些喜欢将代码分布在多行上的人来说:
awk '
{
if (/^[^ \t]/)
$0=x $0
else {
x=$0
sub(/[^ \t].*/, "", x)
}
}
1' file1
将更改限制在 100 至 500 行
awk 'NR>=100 && NR<=500 {if (/^[^ \t]/) $0=x $0; else {x=$0; sub(/[^ \t].*/, "", x);}} 1' file1
就地更改文件
使用 GNU awk:
awk -i inplace 'NR>=100 && NR<=500 {if (/^[^ \t]/) $0=x $0; else {x=$0; sub(/[^ \t].*/, "", x);}} 1' file1
使用 BSD/OSX awk:
awk 'NR>=100 && NR<=500 {if (/^[^ \t]/) $0=x $0; else {x=$0; sub(/[^ \t].*/, "", x);}} 1' file1 >tmp && mv tmp file1
答案2
在 vim 中:
:100,500g/^[^ ]/normal 0ky^jP
解释:
vim 中的“global”命令将对与特定正则表达式匹配的每一行应用 ex 命令。这可以限制在一定范围内的行,在本例中为 100-500。此处的正则表达式为
^[^ ]
这意味着任何字符除了表示行首的空格。ex 命令是
normal 0ky^jP
它的作用是:
0 "Move to the first character on this line
k "Move up one line
y^ "Yank up to the first non-whitespace character
j "Move down one line
P "Paste what we just yanked
运行此操作后,只需调用
:wq
保存文件并退出。您也可以从命令行执行此操作:
vim myfile.txt -c "100,500g/^[^ ]/normal 0ky^jP" -c "wq"
另一个替代解决方案:
:%s/\v^(\s+).*\n\zs(\S)/\1\2
答案3
家庭作业?;->
sed -e '100,500s/^[ ]*/ /' -i file