2014-11-05 85 views
0

我正在尝试编写一个脚本,该脚本从基于文本的数据库中删除一行,如果标题与该标题的字段匹配。例如,我有一个文本文件,它看起来像从bash中的文本文件中删除一行?

Name Age Identification Wage 
Micheal 25 19339 10 
Jane 37 19338 10 
John 21 19334 12 
Peter 35 19330 30 

我调用脚本,并通过标题名称和值,它看起来对包含该标题下该值的线,并及时将其删除。因此,把

./script.sh filename Identification 19334 

应该删除其标识为19334数据库的条目,以便该文件现在看起来是这样:

Name Age Identification Wage 
Micheal 25 19339 10 
Jane 37 19338 10 
Peter 35 19330 30 

我将如何使用awk脚本,或sed的,以删除特定的行?

回答

0
awk -v val=$3 -v hdr=$2 '{for(i=1; i<=NF; i++){if($i==hdr && NR==1){col=i;break}} if($col!=val){print}}' $1 > newfile && mv newfile $1 
1

这AWK不会直接更新文件,但会产生所需的输出:

awk -v header="Identification" -v value="19334" 'NR==1 {for(i=1;i<=NF;i++) cols[$i]=i} $(cols[header])!=value' data 
Name Age Identification Wage 
Micheal 25 19339 10 
Jane 37 19338 10 
Peter 35 19330 30 
  • 可变header使用-v标志
  • value被设置为值以匹配设定Identification使用另一个-v标志
  • 设置cols关联数组,以便为​​列标头分配其字段编号
  • 最后,打印任何行的header表示列不匹配value

匹配value多个行会被删除。

我的bash福较弱,但会做你想要什么:

#!/bin/bash 

newFile=$(awk -v header="$2" -v value="$3" 'NR==1 {for(i=1;i<=NF;i++) cols[$i]=i 
} $(cols[header])!=value' $1); 

echo "$newFile" > $1 

的bash脚本会:

  • 分配awk脚本的结果给newFile变量,其中$2是标题,$3是值,而$1是输入文件。
  • 覆盖的newFile变量的内容在第一个参数的内容,$ 1

如你所描述你可以运行它:

./script.sh data Identification 19334 

从而改变原来的文件,并产生:

Name Age Identification Wage 
Micheal 25 19339 10 
Jane 37 19338 10 
Peter 35 19330 30 

一个需要注意的是拼写错误的标头将覆盖与原来内容的全部文件,并可能离开你想知道为什么它不起作用。

+1

重定向'$ NEWFILE”> $ 1'是可爱的,但不标准的做法。典型的解决方案是'的awk '{脚本的东西}' 文件> file.new && MV file.new file'。这不仅会'awk'程序没有任何错误时''mv' file.new。将巨型文件存储到变量(如$ newFile)中是可能的,但在出现问题时很难调试。祝你们好运。 – shellter 2014-11-05 04:11:55