我有一个名为的设置文件学生
grade1 class1 11 student
grade1 class1 12 student
grade2 class1 21 student
grade2 class2 22 student
......
现在我创建一个测试文件文件读取学生。如果输入年级名和学号,包含两个字符串的行将被复制到学生副本。代码如下:
echo Input gradename and studentnumber
read gradename
read studentnumber
if (input gradename and studnetnumber);
then
echo "the line include them" >> student_copy
例如:
if (input grade1 and 11);
then
echo grade1 class1 11 student >> student_copy
答案1
grep
不符合逻辑和操作(例如match patternA AND patternB
),最接近的做法是构造一个更长的正则表达式来匹配任何可能的变体(例如grep -E 'patternA.*patternB|patternB.*patternA'
)。如果您有很多模式需要匹配,这会变得非常笨拙和难以处理。
完成您想要的操作的最简单方法是使用脚本语言(例如awk
或 )perl
代替grep
.
例如,下面的awk
一行将匹配出现两种模式的任何行。
awk '/patternA/ && /patternB/'
任何模式匹配都可以反转,例如,如果您想匹配包含模式A但不包含模式B的任何行(即并不是手术):
awk '/patternA/ && ! /patternB/'
注意:一种简单的方法是使用grep patternA | grep patternB
(或grep patternA | grep -v patternB
) - 即做实现逻辑 AND(或 AND NOT),但代价是运行多个grep
命令而不是单个awk
orperl
命令。
答案2
假设我们要查找带有grade1
和 的行11
:
示例数据(与问题中的不同)和搜索键:
$ cat student
grade1 class1 11 student
grade1 class1 111 student
grade11 class1 21 student
grade12 class2 22 student
$ grade=grade1
$ num=11
直接 grep 查找给定的字符串,注意与单词边缘匹配的\<
/锚点。\>
这需要它们按顺序排列:
$ grep "^$grade\>.*\<$num\>" student
grade1 class1 11 student
或者用 来-w
匹配完整的单词。
$ < student grep -w "$grade" |grep -w "$num"
grade1 class1 11 student
上述两个内容都可能与行中其他地方的任何类似的单词匹配,因此也许最好使用 awk 来执行此操作并仅比较适当的字段。这假设字段由空格分隔,因此它们本身不能包含任何空格。
$ awk -vg=$grade -vn=$num '$1 == g && $3 == n' student
grade1 class1 11 student
如果您需要包含空格的字段,那么最好有一个不同的分隔符,例如制表符。
答案3
我在下面运行这个命令,
awk '{
if ($1!="grade1" || $3!=11)
print "###";
else
print $0;
}' student
输出是
grade1 class1 11 student
###
###
###
这是预期的输出
但如果我跑测试文件,代码如下:
read -p "Enter gradename: " gradename
read -p "Enter studentnumber: " studentnumber
echo "gradename = $gradename"
echo "studentnumber = $studentnumber"
awk '{
if ($1!="$gradename" || $3!=$studentnumber)
print "###";
else
print $0;
}' student > student2
cat student2
那么输出将是:
Enter gradename: grade1
Enter studentnumber: 11
gradename = grade1
studentnumber = 11
###
###
###
###
很奇怪
答案4
在 awk 的一个衬垫下面,我曾经找到过同样的东西,它工作得很好
for i in `awk '{print $1}' student.txt| sed -r "s/\s+//g"| sed '/^$/d'| sort -u` ; do awk -v i="$i" '$1 ~ i && $3 == "11"{print $0}' student.txt ; done
我检查了学生编号 11 作为常量,所以我在脚本中提到了 $3==11 。
Grade1 和 Grade2 作为“i”中的变量
您可以根据您的要求更改学号。根据要求更改$3==“新生编号”的值