我有以下格式的文件:
.
.
.
Name:abc
Occupation:def
.
.
Name:xyz
Occupation:ghi
.
.
我想提取姓名和职业字段并将其保存在另一个文件 out.txt 中,使用vim
以下格式:
Name:abc
Occupation:def
Name:def
Occupation:ghi
编辑:输入文件中的职业字段位置已更新
答案1
ggyG:e out.txt<cr>p:v/Name\|Occupation/d<cr>:w<cr>
解释
gg # Go to beginning of file
y # yank (copy)
G # to end of file
:e out.txt # Open a new file called out.txt
p # paste what you just copied
:v/Name\|Occupation/d # Delete all lines that don't contain Name or Occupation
:w # save
答案2
编写vim
缓冲区并退出 ( :wq
) 并使用它怎么样:
grep -E '^(Name|Occupation)' your_file >out.txt
该grep
命令将打印出与your_file
我们给它的模式匹配的任何行。这里使用的模式需要扩展正则表达式,这就是我使用切换-E
到grep
.模式如下:
^
表示行的开始(Name|Occupation)
意味着搜索Name
或者Occupation
- 总而言之,正则表达式意味着查找以单词 开头的行
Name
或以单词 开头的行Occupation
。
如果不加考虑,该grep
命令会将所有匹配的行打印到终端。最后一位 ( >out.txt
)重定向命令的输出grep
到文件out.txt
而不是终端。
答案3
维姆:
:g/\./d | sav /tmp/otherFileName
社会经济发展局:
sed '/\(\.\)/d' InputFile >> /tmp/otherFileName
最完美:
:v/^Name*\|^Occupation*/d | s/^Name/\r&/g | sav /tmp/OtherFileName
答案4
之外vim
,其中可以要用来实现结果,有许多命令行工具可以实现相同的结果。以 perl 为例:
perl -n -e '$name=$1 if(/^(Name: .+)$/); print "$name\n\n$_\n" if(/^Occupation: .+/);' < file > out.txt
perl -n
告诉 perl 将标准输入 ( STDIN
) 的每一行包装在 while 循环中。我们可以将文件重定向到STDIN
if 我们< file
在 perl 命令末尾使用。
这具有允许您在我们重定向的每一行上运行 perl 命令的效果file
。
然后,我们指定 perl 应该使用该-e
选项运行哪些命令,如下所示:
'$name=$1 if(/^(Name: .+)$/); print "$name\n\n$_\n" if(/^Occupation: .+/);'
(请注意 perl 指令周围的单引号'
,因为 perl 需要 -e 选项作为命令行上的单个参数)。
至于代码的逻辑,
$name=$1 if(/^(Name: .+)$/);
如果一行^
以开头Name:
,后跟一个或多个字符.+
,然后是该行的结尾$
,如果我们将其包装起来,我们可以存储所有匹配的内容()
,并且它将在一个名为 的特殊变量中可用$1
。所以所有的Name: whatever
都存储在 $1
.然后我们将其分配给一个名为 的变量$name
。
与之前的指令类似,我们接下来要做:
print "$name\n\n$_\n" if(/^Occupation: .+/);'
如果一行^
以开头Occupation:
,后跟一个或多个字符.+
,然后是行尾$
,则打印先前匹配的名称行(存储在 $name 中),两个换行符\n\n
,然后$_
是 while 循环正在处理的当前行的内容(在我们的例子中是匹配 Occupation 行),后面跟着另一个换行符\n
;
最后,我们将此命令的输出重定向到 out.txt > out.txt
。
有一个假设,每个Name:
后面(后面的几行)都有一个与该相关的职业Name:
,如果您有多个职业行,那么您将打印多个姓名和职业。此外,如果姓名没有职业行,则不会打印出来。