私はそれが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
2つの単語が含まれているdesired_string
ため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)
最初の列のデータベース名と2番目の列のユーザー名を一致させたいとします。
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
フィールド区切り文字を変更します。
とにかく、このハッキーソリューションは好きなように機能します。
データベースとユーザー名の周囲に二重引用符を使用することを忘れないでください。
sudo --login -u postgres psql --command="\l" | awk '$1=="postgres" && $3=="postgres" {print $1, $3}'