如果一行包含一些字符串,如何 grep ?

如果一行包含一些字符串,如何 grep ?

我有一个名为的设置文件学生

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命令而不是单个awkorperl命令。

答案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==“新生编号”的值

相关内容