我对编写Bash脚本的世界还很陌生,我需要一些指导。我已经开始编写一个工作脚本,到目前为止一直很好。但是,我现在处于需要收集数据库名称的部分。名称实际上存储在一个文件中,我可以grep它们。
我给出的命令是cat /etc/oratab
,它产生这样的东西:
# This file is used by ORACLE utilities. It is created by root.sh
# and updated by the Database Configuration Assistant when creating
# a database.
# A colon, ':', is used as the field terminator. A new line terminates
# the entry. Lines beginning with a pound sign, '#', are comments.
#
# The first and second fields are the system identifier and home
# directory of the database respectively. The third filed indicates
# to the dbstart utility that the database should , "Y", or should not,
# "N", be brought up at system boot time.
#
OEM:/software/oracle/agent/agent12c/core/12.1.0.3.0:N
*:/software/oracle/agent/agent11g:N
dev068:/software/oracle/ora-10.02.00.04.11:Y
dev299:/software/oracle/ora-10.02.00.04.11:Y
xtst036:/software/oracle/ora-10.02.00.04.11:Y
xtst161:/software/oracle/ora-10.02.00.04.11:Y
dev360:/software/oracle/ora-11.02.00.04.02:Y
dev361:/software/oracle/ora-11.02.00.04.02:Y
xtst215:/software/oracle/ora-11.02.00.04.02:Y
xtst216:/software/oracle/ora-11.02.00.04.02:Y
dev298:/software/oracle/ora-11.02.00.04.03:Y
xtst160:/software/oracle/ora-11.02.00.04.03:Y
我转过身来写grep ":/software/oracle/ora" /etc/oratab
所以它可以抓住我需要的一切,即10个数据库。不是最优雅的方式,但它得到我需要的东西:
dev068:/software/oracle/ora-10.02.00.04.11:Y
dev299:/software/oracle/ora-10.02.00.04.11:Y
xtst036:/software/oracle/ora-10.02.00.04.11:Y
xtst161:/software/oracle/ora-10.02.00.04.11:Y
dev360:/software/oracle/ora-11.02.00.04.02:Y
dev361:/software/oracle/ora-11.02.00.04.02:Y
xtst215:/software/oracle/ora-11.02.00.04.02:Y
xtst216:/software/oracle/ora-11.02.00.04.02:Y
dev298:/software/oracle/ora-11.02.00.04.03:Y
xtst160:/software/oracle/ora-11.02.00.04.03:Y
所以,如果我想获取名称,例如dev068或xtst161,我该怎么办?我认为我需要对这个项目进行前进,将它们存储在一个数组中。如文档中所述,冒号是字段终止符。我怎么能把它鞭在一起所以我有一个数组,如:
dev068
dev299
xtst036
xtst161
dev360
dev361
xtst215
xtst216
dev298
xtst160
我觉得我可能在这里要求太多帮助,但我真的很茫然。我很乐意澄清是否需要。
答案 0 :(得分:2)
使用awk更加简单:
awk -F: -v key='/software/oracle/ora' '$2 ~ key{print $1}' /etc/oratab
dev068
dev299
xtst036
xtst161
dev360
dev361
xtst215
xtst216
dev298
xtst160
要使用以上输出填充BASH数组:
mapfile -t arr < <(awk -F: -v key='/software/oracle/ora' '$2 ~ key{print $1}' /etc/oratab)
检查输出:
declare -p arr
declare -a arr='([0]="dev068" [1]="dev299" [2]="xtst036" [3]="xtst161" [4]="dev360" [5]="dev361" [6]="xtst215" [7]="xtst216" [8]="dev298" [9]="xtst160")'
答案 1 :(得分:1)
我们可以将grep
的输出传递给cut
实用程序来提取第一个字段,将冒号作为字段分隔符。
然后,假设任何名称中没有空格或全局字符(受word splitting和filename expansion约束),我们可以使用command substitution来运行管道,并通过在括号内指定输出来捕获array中的输出。
names=($(grep ':/software/oracle/ora' /etc/oratab| cut -d: -f1;));
请注意,上面的命令实际上在命令替换输出上使用了单词拆分,将名称拆分为结果数组的单独元素。这就是为什么我们必须确保在任何单个数据库名称中都不会出现空格,否则该名称将在内部拆分为数组的单独元素。命令替换输出中我们希望被视为分词分隔符的唯一字符是line feeds,它分隔出来自cut
实用程序的每一行输出。
答案 2 :(得分:1)
你也可以使用awk
:
awk -F: '!/^#/ && $2 ~ /^\/software\/oracle\/ora-/ {print $1}' /etc/oratab
第一个模式排除任何注释掉的行(以#开头)。第二个模式在第二个字段中查找您期望的目录模式。如果满足两个条件,则打印第一个字段,即Oracle SID。 -F:
标志将字段分隔符设置为冒号。
使用您的文件:
dev068
dev299
xtst036
xtst161
dev360
dev361
xtst215
xtst216
dev298
xtst160
根据您正在做的事情,您可以进一步细化它并检查最后一个标志是否设置为Y;虽然这确实表示自动启动,但它有时可用于表明数据库根本不活跃。
您可以将结果放入数组:
declare -a DBS=(`awk -F: -v key='/software/oracle/ora' '$2 ~ key{print $1}' /etc/oratab`)
然后引用${DBS[1]}
(评估为dev299
)等。
答案 3 :(得分:1)
如果您想将它们变成Bash数组:
$ cat > toarr.bash
#!/bin/bash
while read -r line
do
if [[ $line =~ .*Y$ ]] # they seem to end in a "Y"
then
arr[$((i++))]=${line%%:*}
fi
done < file
echo ${arr[*]} # here we print the array arr
$ bash toarr.bash
dev068 dev299 xtst036 xtst161 dev360 dev361 xtst215 xtst216 dev298 xtst160