查明用户名和数据库是否匹配 | grep

查明用户名和数据库是否匹配 | grep

我发现应该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-prod70-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_stringand 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

grepwith-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}'

相关内容