Bash从文件中删除/修改行

时间:2015-03-28 15:12:42

标签: bash

假设我有一个这种格式的文件contacts.txt

number1:name1:phone1:adress1
number2:name2:phone2:adress2

问题是如何从该文件中删除一行(联系人)或修改该联系人的任何组件? 要删除我想要使用此

的行
grep -ve "name1"

并覆盖整个文件,但我确定有更好的方法可以做到这一点......

2 个答案:

答案 0 :(得分:2)

在myfile.txt中进行内联更改,例如

sed -i.bak '/name1/d' myfile.txt

在修改文件之前删除包含name1的行,将在myfile.txt中进行原位更改,它将创建包含原始内容的myfile.txt.bak。

如果要修改该行,请执行以下操作:

sed -i.bak 's/name1/name2/g' myfile.txt

这将搜索name1并将其替换为行中的name2。

答案 1 :(得分:2)

由于数据似乎是以冒号分隔的,因此处理它的最明显的工具是awk。

简单的sed方法的缺点是它们将输入视为纯文本,并不总是产生所需的结果。例如,如果你有史密斯先生和居住在史密斯广场23号的杜利特夫人,那么删除包含史密斯"史密斯"将与史密斯先生一起移除杜利特太太。

另一方面,awk将行拆分为字段,以便您可以轻松地对这些字段进行单独测试。例如,要从文件中删除Smith先生,您可以使用

awk -F : '$2 != "Smith"' myfile.txt

$2代表第二个字段,拨打此电话会选择第二个字段为" Smith"的所有行。 -F :将输入字段分隔符设置为冒号而不是默认空格,以便文件中的行以冒号分割。

它还允许直接修改。例如,要注册史密斯先生的新电话号码,您可以使用

awk -F : 'BEGIN { OFS = FS } $2 == "Smith" { $3 = "555-123456" } { print }' myfile.txt

此处OFS是输出字段分隔符;我们将它设置为与开头的输入字段分隔符相同,以便输出与冒号一样以冒号分隔。其余部分应该是相当不言自明的 - 如果第二个字段是" Smith",则第三个字段设置为" 555-123456",无论转换是否发生(因为那里)没有附加条件),该行打印 1

对于就地编辑,您需要GNU awk 4.1.0或更高版本(在调用中添加-i inplace选项),但由于通常需要备份以防出现问题,我和#39; d只需使用

cp myfile.txt myfile.txt~
awk ... myfile.txt~ > myfile.txt

左右。

你可以找到一个非常有用的awk教程here

1 实际上,代替{ print }更常见的是写短1(作为非零值,当作为条件处理时,它是真的)。如何工作在教程中解释;简而言之:无条件执行没有条件的操作,如果条件为真,则没有操作的条件执行默认操作(打印)。我输入了{ print },因为它对初学者来说不那么容易混淆。