linux - 如何从一行中读取某些单词并将它们存储在 bash 脚本中的不同变量中?
问题描述
我想读取以下命令的输出并将该行中的某些单词存储到某些变量中:
ps -eaf |grep mongod
输出:
root 12911 1 7 16:59 ? 00:05:48 /home/mongo/bin/mongod -f /etc/mongod.conf --replSet mongoReplica --port 27017 --dbpath /home/mongo/data/db/rs0-1 --oplogSize 700
root 22259 7895 0 18:16 pts/4 00:00:00 grep mongod
这里,“12911”是 PID,“/home/mongo/...”是 CMD。我想在这里写一个 if 条件(或者一个 for 循环?)来阅读
- 如果行中有“--port 27017”,则将其PID,“12911”存储在变量中
- 并将“/home/mongo/bin/mongod -f /etc/mongod.conf --replSet mongoReplica --port 27017 --dbpath /home/mongo/data/db/rs0-1 --oplogSize 700”存储在另一个变量中,
- 并将“/home/mongo/data/db/rs0-1”存储在另一个变量中。
这是我到目前为止所拥有的:
ps -eaf | grep mongod | while read -r pid cmd; do
echo "pid: $pid, cmd: $cmd"
done
电流输出:
pid: root, cmd: 12911 1 6 16:59 ? 00:05:56 /home/mongo/bin/mongod -f /etc/mongod.conf --replSet mongoReplica --port 27017 --dbpath /home/mongo/data/db/rs0-1 --oplogSize 700
pid: root, cmd: 24862 24860 0 18:29 pts/4 00:00:00 grep mongod
解决方案
OP评论的假设和收集:
- 可能有多个
mongod
进程(每个 OP 使用while
循环) - 解析的数据需要存储在变量中以用于后续脚本(根据 OP 的评论)
- OP 的
ps
命令允许格式化输出
由于ps
输出在不同的 *nix 实现中可能会有很大差异,我将从ps
输出我们需要的内容开始,例如:
ps -eo pid,cmd # list all processes, only display the pid and command
然后我们可以通过管道将其传递给一个grep
命令,以仅提取感兴趣的行(即包含mongod
和--port 27017
:
ps -eo pid,cmd | grep -- '[m]ongod .*--port 27017`
注意:放在m
括号中应该消除命令的ps
输出记录grep
(即,不需要运行grep -v grep
来跳过grep
一行)
为了展示这个答案如何处理多个mongod
进程,我正在使用两组ps
输出(格式为-o pid,cmd
):
12911 /home/mongo/bin/mongod -f /etc/mongod.conf --replSet mongoReplica --port 27017 --dbpath /home/mongo/data/db/rs0-1 --oplogSize 700
23952 /home/mongo/bin/mongod -f /etc/mongod.conf --replSet mongoReplica --port 27017 --dbpath /home/mongo/data/db/rs0-2 --oplogSize 700
为了允许解析的数据可用于后续处理,我们需要修改while
循环结构以确保我们不会将解析的数据存储在子流程调用中。这表示:
# we replace this:
ps ... | grep ... | while read -r ...
# with this:
while read -r ... ; done < <(ps ... | grep ...)
将所有这些放在一起,我们有:
unset pids cmds dbpaths # make sure nothing in our array variables
i=1 # initialize our array index
while read -r pid cmd
do
pids[i]="${pid}" # store current pid
cmds[i]="${cmd}" # store current cmd
dbpath="${cmd##*--dbpath[ =]}"
dbpaths[i]="${dbpath%% *}" # store current dbpath
((i++)) # increment the array index for next pass through the loop
done < <(ps -eo pid,cmd | grep -- '[m]ongod .*--port 27017')
# at this point we've finished parsing the 'ps' output and follow-on
# processing can access this data via the 3x arrays, eg;
for (( i=1 ; i<=${#pids[@]} ; i++ ))
do
echo "++++++++++++++++ dataset # ${i}"
echo "pid: ${pids[i]}"
echo "cmd: ${cmds[i]}"
echo "dbpath: ${dbpaths[i]}"
done
echo "++++++++++++++++"
这会产生:
++++++++++++++++ dataset # 1
pid: 12911
cmd: /home/mongo/bin/mongod -f /etc/mongod.conf --replSet mongoReplica --port 27017 --dbpath /home/mongo/data/db/rs0-1 --oplogSize 700
dbpath: /home/mongo/data/db/rs0-1
++++++++++++++++ dataset # 2
pid: 23952
cmd: /home/mongo/bin/mongod -f /etc/mongod.conf --replSet mongoReplica --port 27017 --dbpath /home/mongo/data/db/rs0-2 --oplogSize 700
dbpath: /home/mongo/data/db/rs0-2
++++++++++++++++
推荐阅读
- java - Android RecyclerView 阻止回收所有项目
- javascript - 字符串比较 Javascript
- botframework - Azure 机器人通道注册中 Okta 的通用 OAuth 提供程序
- php - 比较 2 个 MYSQL 表以查找匹配数据 PHP
- javascript - Gatsby 中库的条件导入
- java - JAVA List GroupBy 多个字段和 Sum
- javascript - Angular Routing 总是在组件之前显示 url
- makefile - 无法将 grep 的输出存储在 Makefile 中
- android - Flutter - 如何在 AndroidManifest.xml 文件中动态更改谷歌地图 API 密钥
- .net - 用于 PostgreSQL 的 .NET Framework 数据提供程序中出现意外错误