複数行を含むファイルがあります。特定のパターンの後に現れる文字列を取得しようとしています...
これは私が実行したいコマンドです。
sed -n -e 's/^.*DB_PASS=//p' <<< $(cat /root/dadosDB)
しかし、私が望む行だけを提供するのではなく、指定されたパターン以降のすべての項目を提供します。
私の期待:
その行を含む出力のみを返し、DB_PASS
他の行は無視します。
このコマンドが実行するアクションは次のとおりです。
ファイル全体でこのパターンの後に表示されるすべてを印刷し、DB_PASS
その前に表示されるすべてを無視します。
助けてくれてありがとう!
これが私が持っているものですdadosDB
:
DB_USER=myusername
DB_PASS=mypassword
DB_NAME=mydatabase
DB_PASS=
私は次の内容を無視し、次の内容を取得し、その行で停止したいと思います。
実際の出力sed
:
$ sed -n 's/^.*DB_PASS=//p' <<< $(cat /root/dadosDB)
mypassword DB_NAME=mydatabase
私は必要です:
mypassword
ベストアンサー1
この結果を得る理由は、コマンドをsed
ファイルに直接適用するのではなく、コマンド置換の結果に適用するためです。
これは、テキスト処理が実際には適用されないことを意味します。
DB_USER=myusername
DB_PASS=mypassword
DB_NAME=mydatabase
cat
むしろ、これは圧縮された行を引用符で囲まれていないコマンドに置き換えた後にファイルの内容に適用されたコマンドの結果です。
試してみると
echo $(cat /root/dadosDB)
出力が次のようになります。
DB_USER=myusername DB_PASS=mypassword DB_NAME=mydatabase
すべて別々の行ではなく、1行にあります。次のように二重引用符でコマンド置換を入れると
echo "$(cat /root/datosDB)"
改行文字は保持されます。
コアは
cat
コマンドの置き換えを望んでも要求もしません。- 二重引用符を付けずにコマンド置換を使用すると、改行文字が失われます(参照:この質問と回答の例)。(1)
簡単に言うと:
使用
sed -n -e 's/^.*DB_PASS=//p' /root/dadosDB
より具体的に)
sed -n -e 's/^DB_PASS=//p' /root/dadosDB
開始キーワードは他の行を除外しますが、終わり存在するDB_PASS
。
注:あなたが書いた「そしてその行で止まり、下の行は無視してください。」印刷したいという意味だと思います。後でDB_PASS
ただし、次の行は該当しません(技術的には後ろにも表示されます)DB_PASS
。この行で始まる行がさらにあり、DB_PASS
最初の行のみが一致することを確認するには、少し調整する必要があります。
sed -n -e '0,/DB_PASS/s/^DB_PASS=//p' /root/dadosDB
(1)特定のケースの問題は、シェル(Bashと仮定)が引用符で囲まれていない代替項目を使用して「Here-strings」を処理する方法です(@steeldriverが指摘したように)。デモは
cat <<< "$(cat /root/dadosDB)"
そして
cat <<< $(cat /root/dadosDB)
この行動にBash v4.4で変更されました。:以前は、これら2つのコマンドの出力は上記の例と同じでしたecho
。 Bashの将来のバージョンでは、引用符なしのコマンドの置き換えにより、トークン化と複数行出力の後続の圧縮はもはや発生しません。
もっと詳しく知りたいなら確認してみるのもいいと思います
また、以下を使用してスクリプトを確認することをお勧めします。shellcheck
構文(およびその他)のエラーを防ぐために、多くのLinuxディストリビューションでスタンドアロンツールとしても使用できます。