Bash从文件中删除/修改行

Bash从文件中删除/修改行,bash,Bash,假设我有一个这种格式的contacts.txt文件 number1:name1:phone1:adress1 number2:name2:phone2:adress2 问题是如何从该文件中删除一行(联系人)或修改联系人的任何组件? 要删除一行,我想用这个 grep -ve "name1" 并覆盖整个文件,但我确信有更好的方法来做到这一点…在myfile.txt中对例如 sed -i.bak '/name1/d' myfile.txt 将通过删除包含name1的行在myfile.txt中进行

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

number1:name1:phone1:adress1
number2:name2:phone2:adress2
问题是如何从该文件中删除一行(联系人)或修改联系人的任何组件? 要删除一行,我想用这个

grep -ve "name1"

并覆盖整个文件,但我确信有更好的方法来做到这一点…

在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。

由于数据似乎以冒号分隔,因此处理它的最明显工具是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
选项),但由于通常需要有备份以防出错,因此我只使用

cp myfile.txt myfile.txt~
awk ... myfile.txt~ > myfile.txt
大概吧

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


1实际上,与
{print}
不同的是,更常见的做法是编写较短的
1
(作为非零值,在作为条件处理时表示true)。教程中解释了这是如何工作的;简而言之:无条件执行无条件的操作,如果条件为真,则无条件执行默认操作(打印)。我加入了
{print}
,因为它对初学者来说比较容易混淆。

sed将是解决这个问题的一个有用工具,作为烹饪书方法的起点。我在回答你最近删除的问题时删除了它:你在描述对话窗口的行为,不是一个应用程序窗口——所以通过创建并显示JDialog而不是JFrame来创建它。一种快速的方法是使用JOptionPane并让它显示由JPanel持有的GUI。此GUI可以根据需要进行复杂化。另一种方法是创建并显示模式JDialog,
.bak
创建一个名为
original.bak
的原始文件备份文件。要省略创建备份,只需使用
sed-i…