假设我有一个这种格式的文件contacts.txt
number1:name1:phone1:adress1
number2:name2:phone2:adress2
问题是如何从该文件中删除一行(联系人)或修改该联系人的任何组件? 要删除我想要使用此
的行grep -ve "name1"
并覆盖整个文件,但我确定有更好的方法可以做到这一点......
答案 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 }
,因为它对初学者来说不那么容易混淆。