我发现应该grep -w 'desired_string'
只准确地提供行desired_string
,但不能desired_string-22
提供任何变体。
我需要的是检查某个 Postgres 数据库是否由某个用户拥有。所以我尝试了类似的事情
sudo --login -u postgres psql --command="\l" | grep -w 'database-name' | grep -w 'user-name'
但我尝试过的所有变体都不起作用。甚至不
sudo --login -u postgres psql --command="\l" | grep -w "70-prod"
只提供,,70-prod
但70-prod-mod1
也。我发现很多人都在解决这个问题,但似乎没有一个可以使用这个psql
命令。
有人有好主意吗?
预先非常感谢,狼
答案1
不幸的是,你的前提grep -w
被证明是错误的:
echo 'desired_string-22' | grep -w 'desired_string'
desired_string-22
该-w
标志在文档(请参阅 参考资料)中描述man grep
为:
仅选择包含构成整个单词的匹配项的行。测试是匹配的子字符串必须位于行的开头,或者前面有一个非单词组成字符。同样,它必须位于行尾或后跟非单词组成字符。单词组成字符是字母、数字和下划线。
在您的示例中,-
被认为是单词分隔符,所以虽然desired-string
是一个完整的单词,该短语desired_string-22
包含两个单词desired_string
and 22
;因此你的单词匹配desired_string
成功了。
那么,让我们尝试用另一种方式来达到我们想要的结果。
在这里运行psql -l
我得到这个输出:
sudo -u postgres psql --command="\l"
List of databases
Name | Owner | Encoding | Collate | Ctype | ICU Locale | Locale Provider | Access privileges
-----------+----------+----------+-------------+-------------+------------+-----------------+-----------------------
postgres | postgres | UTF8 | en_GB.UTF-8 | en_GB.UTF-8 | | libc |
template0 | postgres | UTF8 | en_GB.UTF-8 | en_GB.UTF-8 | | libc | =c/postgres +
| | | | | | | postgres=CTc/postgres
template1 | postgres | UTF8 | en_GB.UTF-8 | en_GB.UTF-8 | | libc | =c/postgres +
| | | | | | | postgres=CTc/postgres
(3 rows)
我假设您想要匹配第一列中的数据库名称和第二列中的用户名。
db='template0' # Replace with '70-prod' or appropriate
un='postgres' # Replace with appropriate username
sudo --login -u postgres psql --command="\l" |
awk -F'\\|' -v db="$db" -v un="$un" '{ gsub(" ", "") } $1==db && $2==un'
我展示的基本数据库集的输出示例:
template0|postgres|UTF8|en_GB.UTF-8|en_GB.UTF-8||libc|=c/postgres+
请注意,所有空格均已被删除,这|
就是字段分隔符。
如果您实际上并不需要输出,而只是想使用测试结果(我假设您需要,尽管问题中没有明确说明)您可以修改它awk
以便在条件中使用:
db='template0' # Replace with '70-prod' or appropriate
un='postgres' # Replace with appropriate username
if
sudo --login -u postgres psql --command="\l" |
awk -F'\\|' -v db="$db" -v un="$un" 'BEGIN {ss=1} {gsub(" ", "")} $1==db && $2==un {ss=0} END {exit ss}'
then
echo "Found a matching line" >&2
else
echo "No matching line found" >&2
fi
当然,您可以直接查询架构:
db='template0' # Replace with '70-prod' or appropriate
un='postgres' # Replace with appropriate username
sql=" select pd.oid, pd.datname, pd.datdba, pa.rolname
from pg_database pd
join pg_authid pa on pa.oid = pd.datdba
where pd.datname = :'db' and pa.rolname = :'un'
"
sudo -u postgres psql -v db="$db" -v un="$un" <<<"$sql"
答案2
grep
with-w
在您的情况下不起作用,因为-
它也被视为单词分隔符。
sudo --login -u postgres psql --command="\l" | awk '$1=="exactdbmatch" && $3=="exactusermatch" {print $1, $3}'
默认字段分隔符awk
是任何连续的空格。这就是|
PostgreSQL\l
输出中的分隔符被视为$2
值的原因。如果想进入Owner
,$2
可以修改字段分隔符。
不管怎样,这个 hacky 解决方案应该可以完成你想要的工作。
不要忘记在数据库和用户名周围使用双引号。
sudo --login -u postgres psql --command="\l" | awk '$1=="postgres" && $3=="postgres" {print $1, $3}'