我正在尝试在 /etc/oratab 中 grep 查找实例“test”。但只想显示不以注释开头的行。以下是 /etc/oratab 文件中的行:
#test:/u01/appl/oracle/test/db/tech_st/12.1.0.2:N
test:/b001/app/oracle/testrac/db/tech_st/12.1.0.2:N # line added by Agent
这就是我试图获取我感兴趣的详细信息的方式(将以下内容放在 shell 脚本中:
DB_NAME=test
env_var=`cat /etc/oratab |grep $DB_NAME |grep -v '#' |cut -d":" -f 2`
echo $env_var
这里的问题是,由于第二行末尾也有注释,因此它也被忽略。
请帮忙。
问候, RA
答案1
awk
这里会是一个更好的选择:
DB_NAME=test; export DB_NAME
file=$(awk -F: '$1 == ENVIRON["DB_NAME"] {print $2; exit}' < /etc/oratab)
printf '%s\n' "$file"
在 Solaris 上,请确保执行以下操作:
PATH=$(getconf PATH):$PATH
(并#! /usr/xpg4/bin/sh -
在 Solaris 10 及更早版本上使用 if )以获得标准实用程序。或者使用command -p awk
.否则,您可能会得到awk
70 年代的陈旧产品。
答案2
比使用 awk 重写它更简单的解决方案是添加一个简单的 ^ 来指示行的开头:
env_var=`cat /etc/oratab |grep $DB_NAME |grep -v '^#' |cut -d":" -f 2`
删除grep -v '^#'
所有以 # 开头的行并且通常很有用。
答案3
使用sed
,您可以将grep
s 和 the组合cut
在一次传递中:
sed "/^$DB_NAME:/! d;s///;s/:.*//" /etc/oratab
和
/^$DB_NAME:/
选择以;$DB_NAME
开头的所有行:
反转!
匹配,因此以下d
删除了与此模式不匹配的所有行s///
删除最后一个匹配项,在本例中test:
s/:.*//
删除:
以及以下所有内容
答案4
其他答案适用于该示例(文件是 CSV*(冒号分隔值),搜索字符串将是第一个字段,所需输出是第二个字段),但这些约束/条件实际上都不是指出在问题中。而且,虽然问题要求一个排除以下行的命令开始带有评论,这可能不是OP真正想要的。 (像这样的行怎么样unwanted line:blah:blah #test
,其中包含test
在评论中?)OP想要的答案是
grep '^[^#]*test' /etc/oratab
或者
grep "^[^#]*$DBNAME" /etc/oratab
它搜索出现的行test
,并且它之前的所有字符都不是#
。
像往常一样,您应该始终引用您的 shell 变量引用(例如,"$DB_NAME"
和"$env_var"
),除非您有充分的理由不这样做,并且您确定您知道自己在做什么。和,正如斯特凡·查泽拉斯 (Stéphane Chazelas) 指出的,如果$DBNAME
看起来像一个不平凡的正则表达式(例如,它包含.
,*
或[
... ]
),可能会出现不需要的结果。