rpmベースのLinuxディストリビューション(RHEL / Red Hat、Fedora、CentOSなど)で使用されている場合、dnf
ユーティリティyum
はユーザーが読みやすくするために自動的に行を置き換えます。これは、パイプによるデータ処理を非常に迷惑にするため、問題になります。
たとえば、
$ dnf search jenkins-ssh-credentials-plugin-javadoc
Last metadata expiration check: 6 days, 15:30:08 ago on Thu Sep 1 21:09:10 2016.
============= N/S Matched: jenkins-ssh-credentials-plugin-javadoc =============
jenkins-ssh-credentials-plugin-javadoc.noarch : Javadoc for jenkins-ssh-credentials-plugin
$ dnf search jenkins-ssh-credentials-plugin-javadoc | grep ssh
====== N/S Matched: jenkins-ssh-credentials-plugin-javadoc =======
jenkins-ssh-credentials-plugin-javadoc.noarch : Javadoc for
: jenkins-ssh-credentials-plugin
DNFの出力が出てくると、通常はgrep
ユーザーに表示するのとまったく異なる方法でデータをラップすることにしました。
この動作に関していくつかの質問が提起されました(#584525、#986740CLOSED NOTABUG
)そして、「Yumはパイプラインに適していないか、または適切ではないテキストベースのインタラクティブなユーザーインターフェイス」なので、質問は常に終了しました。 Red Hat 開発者のソリューションは、「作業に別のツールを使用する」ことです。
repoquery
特に、提供された方法(インストールなど)が正しく機能しない場合は、これを行う必要があるのは不合理です。存在するdnf
このデータの出力を解析するには、ユーティリティ内にさらにパッケージをインストールする必要があります。
理想的には、ユーザーはパイプラインでデータを使用できます。代わりに、データを使用可能にするために使用できる単純な1行コードがあればよいでしょう。
答え1
sed
名前で書かれた「例」コマンド/注文の素晴らしいリストがありますsed1line.txt
(http://sed.sourceforge.net/sed1line.txt)。この状況に役立つ良い例はこの記事にあります。
# if a line begins with an equal sign, append it to the previous line
# and replace the "=" with a single space
sed -e :a -e '$!N;s/\n=/ /;ta' -e 'P;D'
dnf
/出力の場合、yum
改行文字は1つ以上の空白のインスタンスで始まり、その後にコロン(:)、そしてより多くの空白が続くことを知っています。この知識を使用してsedの例を変更して、これを説明し、次の行を追加できます。
sed -r -e :a -e '$!N;s/\n[[:space:]]+://;ta' -e 'P;D'
この場合、私たちは決定を下す必要があります。+
「拡張された」正規表現セットの一部として、-r
そのシンボルを使用するために追加する必要があります。または、そのシンボルをその位置(ゼロ以上のスペースに一致する)に使用するように+
置き換える必要があります。*
どちらも大丈夫です。上記の例は賢明に言えば正確です。
結果は次のとおりです。
$ dnf search jenkins-ssh-credentials-plugin-javadoc | sed -r -e :a -e '$!N;s/\n[[:space:]]+://;ta' -e 'P;D' | grep ssh
============= N/S Matched: jenkins-ssh-credentials-plugin-javadoc ==============
jenkins-ssh-credentials-plugin-javadoc.noarch : Javadoc for jenkins-ssh-credentials-plugin
ご覧のとおり、今grep
のように動作します。これにより、出力形式をより創造的に指定できるため、パッケージリストをより簡単にスキャンできます。
$ dnf search ssh | sed -r -e :a -e '$!N;s/\n[[:space:]]+://;ta' -e 'P;D' | sort | awk -F: '!($1~/^====/) {printf "%-40s : %s\n", $1, substr($0, index($0, $2))}'
ansible.noarch : SSH-based configuration management, deployment, and task execution system
apache-sshd-javadoc.noarch : API documentation for apache-sshd
apache-sshd.noarch : Apache SSHD
autossh.x86_64 : Utility to autorestart SSH tunnels
bareftp.x86_64 : File transfer client supporting the FTP, FTP over SSL/TLS (FTPS) and SSH
belier.noarch : Generates scripts allowing you to chain many ssh connections
btrfs-sxbackup.noarch : Incremental btrfs snapshot backups with push/pull support via SSH
...
trilead-ssh2.noarch : SSH-2 protocol implementation in pure Java
WebShell.noarch : SSL server for web-based SSH access from browsers and mobile devices
x11-ssh-askpass.x86_64 : A passphrase dialog for X and not only for OpenSSH
答え2
yum
そしてdnf
進行メッセージを書き込むには、キャリッジリターン文字を使用して新しい行を置き換えます。このメッセージはパック。grep
行に含まれる制御文字がないと仮定すると、この目的のために設計されていません。grep
端末についていくつかの仮定がありますが、それは他の物語。
sedスクリプトを使用して、重複印刷された行を「最終」行にフィルタリングしました(重複印刷部分をすべて削除)。例ではscript2log.sed
、
# $Id: script2log.sed,v 1.3 2015/02/04 23:50:12 tom Exp $
#
# Trim ordinary ANSI sequences, then OSC sequences, then backspace
# sequences, then trailing CR's and finally overstruck sections of
# lines.
#
# There are still several interesting cases which cannot be handled
# with a script of this sort. For example:
# CSI K (clear line)
# cursor movement within the line
s/␛[[][<=>?]\{0,1\}[;0-9]*[@-~]//g
s/␛[]][^␛]*␇//g
s/␛[]][^␛]*␛\\//g
:loop
s/[^␈]␈\(.\)/\1/g
t loop
s/␍␍*$//g
s/^.*␍//g
s/␛[^[]//g
これは、最初に1行の末尾のキャリッジリターンの数を削除してから、キャリッジリターンを含む行部分を削除する2つのコマンドを使用して実行されます。残りは、作成する行の最後のコピーです(必要なもの)。
s/␍␍*$//g
s/^.*␍//g
(はい、これはスクリプトのキャリッジリターンです)。
yum
(or)の出力をキャプチャするときにdnf
パイプに接続しようとしませんgrep
(確かに望ましくない結果が生成されます)。代わりに、私はscript
出力をキャプチャし、後処理を使用しましたsed
。たとえば、次のようになります。
script -c "yum upgrade"
sed -f script2log.sed typescript >upgrade.log