web-dev-qa-db-ja.com

コマンドを一緒にパイピングする良い例は何ですか?

コマンドラインでパイプの概念を学ぶのを手伝っている場合、どのような例を使用しますか?実際に思いついた例は次のとおりです。

cat whatever.txt | less

それは最良の例ではない、つまり1つのステップしかないためです。 |の優れた、しかし根本的な用途は何ですか?

理想的には、これから紹介する例では、独立して実行でき、パイプで一緒に表示できる出力自体を備えたプログラムを使用します。

33
Matthew

実際のシナリオに基づいて、少し複雑な例を紹介します。

問題

コマンドconkyがデスクトップで応答を停止し、手動で終了したいとします。 Unixを少し知っているので、kill <PID>コマンドを実行する必要があることはわかっています。 PIDを取得するために、psまたはtop、またはUnixディストリビューションから提供されたツールを使用できます。しかし、これを1つのコマンドでどのように実行できますか?

回答

$ ps aux | grep conky | grep -v grep | awk '{print $2}' | xargs kill

免責事項:このコマンドは特定の場合にのみ機能します。端末にコピー/貼り付けして使用を開始しないでください。疑いもなくプロセスが強制終了される可能性があります。むしろ学ぶそれを構築する方法

仕組み

1- ps aux

このコマンドは、実行中のプロセスのリストとそれらに関するいくつかの情報を出力します。興味深い情報は、2列目に各プロセスのPIDを出力することです。これは私のボックスのコマンドの出力からの抜粋です:

$ ps aux
 rahmu     1925  0.0  0.1 129328  6112 ?        S    11:55   0:06 tint2
 rahmu     1931  0.0  0.3 154992 12108 ?        S    11:55   0:00 volumeicon
 rahmu     1933  0.1  0.2 134716  9460 ?        S    11:55   0:24 parcellite
 rahmu     1940  0.0  0.0  30416  3008 ?        S    11:55   0:10 xcompmgr -cC -t-5 -l-5 -r4.2 -o.55 -D6
 rahmu     1941  0.0  0.2 160336  8928 ?        Ss   11:55   0:00 xfce4-power-manager
 rahmu     1943  0.0  0.0  32792  1964 ?        S    11:55   0:00 /usr/lib/xfconf/xfconfd
 rahmu     1945  0.0  0.0  17584  1292 ?        S    11:55   0:00 /usr/lib/gamin/gam_server
 rahmu     1946  0.0  0.5 203016 19552 ?        S    11:55   0:00 python /usr/bin/system-config-printer-applet
 rahmu     1947  0.0  0.3 171840 12872 ?        S    11:55   0:00 nm-applet --sm-disable
 rahmu     1948  0.2  0.0 276000  3564 ?        Sl   11:55   0:38 conky -q

2- grep conky

興味があるのは1つのプロセスだけなので、grepを使用して、自分のプログラムconkyに対応するエントリを見つけます。

$ ps aux | grep conky
 rahmu     1948  0.2  0.0 276000  3564 ?        Sl   11:55   0:39 conky -q
 rahmu     3233  0.0  0.0   7592   840 pts/1    S+   16:55   0:00 grep conky

3- grep -v grep

手順2で確認できるように、コマンドpsは、リストにgrep conkyプロセスを出力します(結局、これは実行中のプロセスです)。それをフィルタリングするために、grep -v grepを実行できます。オプション-vは、すべての行に一致するようにgrepに指示します除くパターンを含む行に一致します。

$ ps aux | grep conky | grep -v grep
 rahmu     1948  0.2  0.0 276000  3564 ?        Sl   11:55   0:39 conky -q

注:単一のgrep呼び出しでステップ2と3を実行する方法を知りたいです

4- awk '{print $2}'

ターゲットプロセスを分離したので、 PIDを取得したい。つまり、出力の2番目のワードを取得したいと思います。幸運なことに、ほとんど(すべて?)の最新のuniceは、テーブルデータで不思議に思うスクリプト言語であるawkのいくつかのバージョンを提供します。私たちの仕事はprint $2と同じくらい簡単になります。

$ ps aux | grep conky | grep -v grep | awk '{print $2}'
 1948

5- xargs kill

PIDを持っています。 killに渡すだけです。これを行うには、xargsを使用します。

xargs killは、入力(この場合はパイプから)から読み取り、commandから構成されますkill <items><items>は入力から読み取ったものです) 、作成したコマンドを実行します。私たちのケースではkill 1948を実行します。任務完了。

最後の言葉

使用しているUNIXのバージョンによっては、特定のプログラムの動作が少し異なる場合があります(たとえば、psは$ 3列にPIDを出力する場合があります)。何かが間違っている、または違っているように見える場合は、ベンダーのドキュメントを読んでください(または、manページ)。また、配管が長いと危険な場合がありますのでご注意ください。特にkillrmなどのコマンドを使用する場合は、何も想定しないでください。たとえば、「conky」(または「Aconkyous」)という名前の別のユーザーがいる場合、私のコマンドは実行中のプロセスもすべて強制終了する可能性があります。

特に長いパイプの場合は注意が必要です。ここで行ったように、対話的に構築する方が、仮定をして後で後悔するよりも常に優れています。

34
rahmu

私のお気に入りはこれです:

youtube-dl $1 -q -o - | ffmpeg -i - $2

$1から渡された特定のYouTube URLから動画をダウンロードし、$2から渡されたファイルとして出力します。ファイルが静かに-qでSTDOUT -o -に出力され、ffmpegにパイプされて-i -によって入力として使用されることに注意してください。

特にLinuxの初心者にとって、これはコマンドラインが便利でGUIツールを使用するよりも簡単にできる理由の実用的な例となるでしょう。 YouTubeからビデオをダウンロードし、そのサウンドをMP3に変換するのにどれくらい時間がかかるかわかりません。上記の行は数秒でそれを行うことができます。

15
Baarn

一般的な用途(読み取り:ほとんどの場合の使用方法)は、何らかの理由で、さまざまな処理タスクを実行するためにいくつかのツールでデータを実行する必要がある場合です。

だから私はtheパイプの使用はいくつかのビルディングブロック(異なるUNIXツール)を一緒にアセンブルするための接着剤と同じだと思います。 Ulrichが言ったように、sortおよびuniqは一般的なスタンザです。

聴衆によっては、このパイプの使用法を強調したい場合、たとえば、次のように開始できます。「ねえ、このシラバスには、論文と講義ノートを含むいくつかの興味深いPDFへのリンクがありますが、一部は繰り返されています。どういうわけかこれを自動化しますか?」

次に、lynx --dump --listonlyがリンクのリストを取得する方法、grep.pdfで終わるリンクをフィルタリングする方法、colrmまたはsedがどのようにできるかを示すことができますlynxが各URLに残した書き込み数を取り除く、sortuniqが重複を取り除く方法、最後にwget -i -を使用して取得する方法ファイル(もちろん--waitを使用して、サーバーにやさしくなります)。

これは複雑な例だと思います。一方、パイプを使用してシェルに一度に実行させると、パイプの力を示すのに役立ちます。

9
njsg

ようやく、1年半ほど前に作ったこのワンライナーの混乱を共有できるようになりました...

while read in; do Host "$in"; done < sites.txt | grep -iv "GOOGLE" | grep -E '1\.2\.3\.4|5\.6\.7\.8' | sed -e 's/has\ address\ 216.70.91.72//' | sed -e 's/has\ address\ 94.23.33.92//' | while read sites; do curl -sL -w "%{http_code} %{url_effective}\\n" "$sites" -o /dev/null; done | grep -ivE '4.*|5.*' | sed -e 's/200//' | sed -e 's/HTTP/http/'

それ...

  1. Sites.txtを読み取ります
  2. それぞれで「ホスト」を実行します(後から考えると、Dig + shortを使用すると、これが非常に簡単になります)
  3. 「GOOGLE」を含む行を削除します-これらはmxレコードです
  4. 2つのIPのいずれかを持つ行を取得します
  5. リスト内の各サイトからhttpステータスコードを取得します
  6. 4xxまたは5xxを返すサイトを削除します
  7. それを返したサイトから「200」を取り除きます
  8. 「HTTP」を「http」に置き換えます-純粋に美的であり、実際の理由はありません。

これは、1つのPython=スクリプトで十分にうまくいくはずです。

2
tanner

私は良いことについて正確には知りませんが、grepを介したパイプ処理は最も一般的な用途の1つである必要があり、おそらくwc -lがそれに続きます。 (はい、grepにはほとんど知られていない-cスイッチがあります。)

別の一般的なスタンザは| sort | uniqです。これは、uniqが入力のソートを必要とするためです。

2
Ulrich Schwarz

これが最初に頭に浮かんだことです...

mysqldumpは、データ、スキーマ、およびオプションでプロシージャと関数をstdoutに送信するコンソールアプリケーションです。通常、バックアップ用のファイルにリダイレクトされます。

mysqldump <options> > mydb.dump

これにより、非圧縮のSQLスクリプトが得られます。スペースを節約するために、bzip2で圧縮できます。

bzip2 mydb.dump

または、両方を1つのステップで実行することもできます。

mysqldump <options> | bzip2 > mydb.dump.bz2

上記の例では、mysqldumpからのstdoutがbzip2にパイプされ、その出力がファイルにリダイレクトされます。

2
Sean C.

この例では必要ありませんが、次のとおりです。

$ ps aux | grep -v grep | grep conky

... grepsの順序を逆にすると、色付けは保持されますが、効率はかなり低下します。おそらく大きなリストでは、色は関係ありません。

また、このWebページは次のことを提案しています。

https://stackoverflow.com/questions/9375711/more-elegant-ps-aux-grep-v-grep

> Johnsywebが2012年2月21日10:31に回答
>通常のトリックはこれです:
> ps aux | grep '[t] erminal' 
>これは端末を含む行に一致しますが、grep '[t] erminal'はそうではありません!
>多くの種類のUnixでも機能します。

...しかし、1つの文字(プロセス 'X'など)を探している場合は機能しません。

2
anonymuse

これは、1つのコマンドで複数のパイプを使用する場合の例です。これは、gawkを使用してMySQLの一般クエリログ($ OFILE)を検索し、拒否されたログインを見つけます。次に、そのリストを名前でソートし、そのリストをuniqにパイプして、出現回数をカウントします。次に、パイプして、最後にもう一度ソートして、カウントされたリストを数値でソートします...

gawk '{ for (x=1;x<=NF;x++) if ( $x~"Access" && $(x+4)~".*@.*") print $(x+4)}' $OFILE | sort | uniq -c | sort -n
1
Rob Berkes

パイプはフィルターとトランスレーターで最適に機能します

find /usr/bin/ |                #produce 
sed 's:.*/::'  |                #translate: strip directory part
grep -i '^z'   |                #filter   : select items starting with z
xargs -d '\n' aFinalConsumer    #consume  

このようにして、データは1つのプログラムから次のプログラムにバッファリングで流れることができ、すべてのデータが一度にメモリにある必要はありません。

1
PSkocik

以下は、xauthがオプションではないときにDISPLAY変数を設定するために使用した例です...

export DISPLAY=\`who am i |awk '{print $NF}' | sed 's/[()]//g'`":0.0"

最初のコマンドは、必要なデータ、つまりホスト名またはIPを取得します。 2番目のコマンドは、そのデータ(最後のフィールド)のみを取得します。最後に、最後のコマンドは括弧をデータから削除します。

0
Scott Hoffman

cat filename | lessは単にless filename

これは私が毎日使用するピップの例です(ただし、悪い例かもしれません):ls -la | more -c

Scott hoffmanとnjsgの回答がより良い例です。

0
DwB

フォルダーサイズをソートして分析したい任意のディレクトリでこれを実行します(次にENDキーで下にスクロールします)。

du -m| sort -n| less

Sortiert nachOrdnergrösse

0
xubunuser

コマンドパイピングは、最初のコマンドの出力を次の入力として入力できると感じる場所ならどこでも使用できます。

例。

  1. テキストファイルを使用すると、テキストファイルをgrepに渡して特定のテキスト行を見つけることができます。次に、出力をsedまたはawkに渡して、行の特定の部分を変更または印刷できます。

猫の例txt | grep {some_line} | awk {some_command}

  1. プロセスを使用すると、プロセスを強制終了するコマンドを送信するためにパイピングを使用できます。

これは、実行したコマンドの出力を別のコマンドの入力にすることができる場合は、それらをパイプ処理できるという単純な概念です。

0
Piyush Jain

方法: パターンを検索して、最後に発生したパターンを表示しますか?

段階的に構築できるパイプコンテキストでtailsedgrepを使用する方法を示します。

0
dsz