![如何有选择地从文件中复制详细信息并将其粘贴到新文件中?](https://linux22.com/image/1093304/%E5%A6%82%E4%BD%95%E6%9C%89%E9%80%89%E6%8B%A9%E5%9C%B0%E4%BB%8E%E6%96%87%E4%BB%B6%E4%B8%AD%E5%A4%8D%E5%88%B6%E8%AF%A6%E7%BB%86%E4%BF%A1%E6%81%AF%E5%B9%B6%E5%B0%86%E5%85%B6%E7%B2%98%E8%B4%B4%E5%88%B0%E6%96%B0%E6%96%87%E4%BB%B6%E4%B8%AD%EF%BC%9F.png)
我有一个包含我的个人信息的文件 (.txt)。我如何通过终端从文件中复制一些信息并将其放入新文件中.txt
?
例如,如果这是文件的内容:
name : farah age : 23 phone number : 0123 education : degree
我怎样才能仅复制年龄和电话号码并将它们输出到新.txt
文件?
答案1
有几种方法可以做到这一点。如果你的文件具有一些已知结构,则可以使用grep
。该grep
命令在文件中搜索特定短语并返回与该短语匹配的行。因此,如果你的文件看起来像
姓名:莎莉
出生日期:1976 年 7 月 31 日
地址:1234 Main St.
社会保险号:123-45-6789
你可以运行它grep Name info.txt
,它会返回Name: Sally
。然后你可以重定向输出到另一个文件。因此调用
grep Name info.txt > info2.txt
会将该行输出到新文件 info2.txt。如果要添加新行,可以执行
grep Address info.txt >> info2.txt
否则该文件将被覆盖。
您还可以学习使用命令行文本编辑器,例如vim。
答案2
答案3
您显示的文件在一行中包含所有详细信息:
name : farah age : 23 phone number : 0123 education : degree
我假设您可以将age :
等硬编码到命令中,但其后面的文本会有所不同,并且细节可能不按给定的顺序排列或不连续。
grep
您可以使用的标志提取行的部分内容-o
。这样只会打印匹配的部分,而不是整行。
如果要包含age :
和phone number :
部分,则可以使用-e
标志来指定多个匹配或交替。
$ grep -oe 'age : [^ ]*' -e 'phone number : [^ ]*' file
age : 23
phone number : 0123
该表达式[^ ]*
表示任意数量的非空格字符,因此它匹配直到age :
下一个空格之后的字符。
替换file
为包含您的详细信息的文件的名称。您可以使用运算符将输出重定向到新文件来写入新文件>
,如下所示:
grep -oe 'age : [^ ]*' -e 'phone number : [^ ]*' file > outfile
执行此操作时,您将看不到任何输出。您应该先检查输出,然后添加重定向。
这是交替的示例。我们使用-E
标志来指示grep
使用扩展正则表达式。语法是(pattern1|pattern2)
- 这匹配pattern1
和/或pattern2
。如果找到其中一个,它将被打印(无论是否找到另一个)。我现在使用+
表示至少一个前一个字符,而不是*
表示零个或多个前一个字符。在这种情况下,它们都同样有效。
$ grep -Eo '(age : [^ ]+|phone number : [^ ]+)' file
age : 23
phone number : 0123
如果要省略age :
和phone number:
部分,可以使用-P
标志来要求grep
使用与 Perl 兼容的正则表达式。这支持交替,也是一种匹配文本的方式后给定模式:
$ grep -Po '(age : \K[^ ]+|phone number : \K[^ ]+)' file
23
0123
如果您想要以不同的方式格式化文本,则可以使用sed
,例如:
$ sed -r 's/.*(age) : ([^ ]*).*(phone number) : ([^ ]*).*/\1:\2 | \3:\4/' file
age:23 | phone number:0123
这取决于age
是否在之前phone number
,因此如果不是这种情况,请进行相应调整。如果您不能依赖顺序,则可以使用这个非常复杂的命令:
$ sed -r 's/(.*)(phone number : [^ ]+)(.*) .*/\2 \1\4/; s/(phone number) : ([^ ]+) .*(age) : ([^ ]+).*/\1: \2 | \3: \4/' file
phone number: 0123 | age: 23
这会重新排列行,使该phone number :
部分在每一行中都排在第一位,然后进行第二次替换以选择所需的细节。我把这里使用的技术归功于muru 的这个回答。
sed
前面解释未涉及的命令的注释
-r
使用扩展的正则表达式来获得更易读的命令(GNUsed
理解-E
相同的含义)s/old/new/
old
用。。。来代替new
(pattern)
保存pattern
以供以后参考,使用\1
或\2
等(对应于捕获组出现的从左到右的顺序 - 请注意sed
最多只能保存其中的 7 个!)。.
任意字符,因此.*
代表任意数量的任意字符。;
分隔命令,如同在 shell 中一样。
答案4
假设输入文件details.txt
包含:
name: farah
age: 23
phone number: 0123
education: degree
您可以通过扩展 grep 选择行“name”和“phone”,并将输出重定向到 new.txt:
grep -E "age:|phone number:" details.txt > new.txt
这将生成 new.txt 文件,内容如下:
age: 23
phone number: 0123
怎么运行的:
Grep 仅打印匹配的行。-E
启用扩展正则表达式的选项使您可以使用|
(替代)。请记住引用整个模式,这样|
grep 就会对其进行解释。否则 shell 将尝试进行解释。您不希望出现这种情况。