我正在编写一个小的BASH脚本,该脚本读取带有名称的csv文件,并提示用户输入要删除的名称。 csv文件如下所示:
Smith,John
Jackie,Jackson
要从列表中删除的人的名字和姓氏保存在bash变量$first_name
和$last_name.
这是我到目前为止所做的:
cat file.csv | awk -F',' -v last="$last_name" -v first="$first_name" ' ($1 != last || $2 != first) { print } ' > tmpfile1
这很好用。但是,即使没有员工匹配该名称,它仍会输出到tmpfile1
。我想要的是:
if ($1 != last || $2 != first) { print } > tmpfile1 ; else { print "No Match Found." }
我是awk的新手,无法让最后一部分工作。
注意:我不想使用像grep -v "$last_name,$first_name"
这样的东西;我想使用过滤功能。
答案 0 :(得分:1)
您可以直接在awk脚本中重定向,只输出找到的匹配项。
awk -F',' -v last="$last_name" -v first="$first_name" '
$1==last && $2==first {next}
{print > "tmpfile"}
' file.csv
以下是您的脚本与此之间的一些差异....
请注意,如果需要,您可以使用-v
指定要在传入的变量中重定向的目标。
如果你真的想要“找不到匹配”错误,你可以设置一个标志,然后在awk中使用END
特殊条件......
awk -F',' -v last="$last_name" -v first="$first_name" '
$1==last && $2==first { found=1; next }
{ print > "tmpfile" }
END { if (!found) print "No match found." > "/dev/stderr" }
' file.csv
如果你不希望在没有找到匹配的情况下创建tmpfile,你需要扫描文件TWICE,一次验证是否匹配,一次打印,或者是否没有风险文件的大小对于可用内存来说太大了,你可以保留一个缓冲区:
awk -F',' -v last="$last_name" -v first="$first_name" '
$1==last && $2==first { next }
{ output = (output ? output ORS : "" ) $0 }
END {
if (output)
print output > "tmpfile"
else
print "No match found." > "/dev/stderr"
}
' file.csv
免责声明:我没有测试任何这些。 :)
答案 1 :(得分:0)
您可以对文件执行两次传递,或者您可以将所有文件排到目前为止在内存中排队,如果到达没有匹配的END块,则会失败。
#include <iostream>
#include <cstdlib>
using namespace std;
class student{
string name;
double ID;
int age;
string course;
public:
void setName(string sname);
void setID(double sID);
void setAge(int sage);
void setcourse(string scourse);
string getName();
double getID();
int getage();
string getcourse();
}
void student::setName(string sname){
name = sname;
}
void student::setID(double sID){
ID = sID;
}
void student::setAge(int sage){
age = sage;
}
void student::setcourse(string scourse){
course = scourse;
}
string student::getName(){
return name;
}
double student::getID(){
return ID;
}
int student::getage(){
return age;
}
string student::getcourse(){
return course;
}
void ReadData(student data[], int n);
int main()
{
student *record;
int nItems;
int i;
cout << "How many students are there to process? : ";
cin >> nItems;
record = new student[nItems];
ReadData(record, nItems);
for (i=0;i<nItems;i++)
student i;
cout << record[i].name << " " << record[i].ID << " " record[i].age << " " record[i].course << endl;
return 0;
}
s
void ReadData(student data[], int n) {
int i;
for (i=0;i<n;i++) {
cout << "Enter a name : ";
cin >> data[i].name;
cout << "Enter a ID as double : ";
cin >> data[i].ID;
cout << "Enter age as integer :"
cin >> data[i].age;
cout << "Enter course as string :";
cin >> data[i].course;
}
}
这要求您有足够的内存来存储整个文件(当没有匹配时这将是必需的。)
答案 2 :(得分:0)
使用bash脚本,您可以测试awk是否打印出来。
如果是,请删除tmp文件。
c=$(awk -F',' -v a="$last_name" -v b="$first_name" '
$1==a && $2==b {c=1;next}
{print > "tmpfile"}
END{if (!c){print "no match"}}' infile)
[ -n "$c" ] && { echo "$c"; rm tmpfile;}