我的目标是编写一个shell脚本,将已经过滤掉的用户从文件中删除,并检查这些用户是否具有特定的字符串,如果有,则将其标记为主要,如果不是,则将其标记为非主要。我的麻烦来自我的第一个if语句,而且我不确定grep是否是插入if语句的正确方法。这是我所拥有的:
(
while read i
do
username=`echo $i | grep -v 'CMPSC 1513' | grep -P -v '(?!.*CPSMA 2923)CPSMA' | cut -d'|' -f2`
fullname=`echo $i | grep -v 'CMPSC 1513' | grep -P -v '(?!.*CPSMA 2923)CPSMA' | cut -d'|' -f3`
id=`echo $i | grep -v 'CMPSC 1513' | grep -P -v '(?!.*CPSMA 2923)CPSMA' | cut -d'|' -f4`
if [ $username ]
then
if grep -q "|0510"
then
echo $username":(password):(UID):(GID):"$fullname"+"$id":/home/STUDENTS/majors:/bin/bash"
else
echo $username":(password):(UID):(GID):"$fullname"+"$id":/home/STUDENTS/nonmajors:/bin/bash"
fi
fi
done
)<./cs_roster.txt
仅提供一些信息,它包含在while循环中。在while循环中,我确定列出的人员应该是专业还是非专业,并且我的if [$ username]是否已经过测试,并且确实返回了所有正确的用户。此时,while循环仅运行一次,然后停止。
答案 0 :(得分:1)
只需除去方括号并将$i
传递到grep
:
if echo $i | grep -q "|0510"
在您的代码示例中,grep
没有任何内容。
答案 1 :(得分:0)
发生“预期的二进制运算符”是因为您正在调用带有参数“ grep”和“ -q”的命令[
(根本就没有调用grep),并且[
期望有一个您已指定-q
的二进制运算符。 [
是命令,与grep
或ls
或cat
一样对待。最好(IMO)将其拼写为test
,并且当使用名称test
进行调用时,它的最后一个参数不必为]
。如果要在if语句中使用grep
,请执行以下操作:
if echo "$username" | grep -q "|0510"; then ...
(尽管我怀疑,根据具体情况,还有更好的方法可以实现您的目标。)
if语句的基本语法为if pipeline; then...
。在通常情况下,管道是简单的命令test
,在历史记录的某个时候,决定为[
命令提供名称test
,并添加请注意,其最终参数必须为]
。我相信这样做是为了使语句看起来更自然,就像[
是该语言的运算符一样。只需忽略[
并始终使用test
,就可以避免很多混乱。
答案 2 :(得分:0)
您可以将此代码用作练习。为此编写一个awk
脚本,或以类似
while IFS='|' read -r f1 username fullname id otherfields; do
# I don't know which field you want to test. I will rest with id
if [[ $id =~ ^0510 ]]; then
subdir=majors
else
subdir=nonmajors
fi
echo "${username}:(password):(UID):(GID):${fullname}+${id}:/home/STUDENTS/${subdir}:/bin/bash"
done < <( grep -v 'CMPSC 1513' ./cs_roster.txt | grep -P -v '(?!.*CPSMA 2923)CPSMA' )
这对于学习一些bash语法非常有用,但是考虑使用awk
脚本来避免while循环。