df
からの次の出力を検討してください。
Filesystem Size Used Avail Use% Mounted on
/dev/sda1 23G 6.1G 16G 29% /
udev 10M 0 10M 0% /dev
tmpfs 397M 420K 397M 1% /run
tmpfs 5.0M 0 5.0M 0% /run/lock
tmpfs 1.8G 904K 1.8G 1% /run/shm
/dev/sda6 890G 324G 521G 39% /home
/dev/sdb1 459G 267G 169G 62% /home/user/mnt
none 4.0K 0 4.0K 0% /sys/fs/cgroup
"/dev"
で始まる行のみを表示し、見出しは保持し、その他はすべて除外するにはどうすればよいですか。一時ファイルや変数を使用することに頼る必要がないようにもしたいですか?注:見出しはロケールに依存するため、正規表現では見出しをキャッチできません。
単純なgrep
よりも少し洗練されたアプローチを使用します。
awk
df -h | awk 'NR==1 || /^\/dev/'
NR
は現在の行番号なので、これが最初の行である場合は上記のawk
スクリプトレットが出力されますまたは現在の行は/dev
で始まります。これを投稿した後、@ 1_CRの回答と同じであることがわかります。しかたがない...
Perl
df -h | Perl -ne 'print if (/^\/dev/ || $.==1)'
同じ考え方ですが、Perlでは特殊変数$.
が現在の行番号です。別の方法は
df -h | Perl -pe '$_="" unless /^\/dev/ || $.==1'
-p
スイッチは、入力ファイルのすべての行を出力します。現在の行の値は$_
に保持されるため、現在の行が必要でない限り、$_
を空に設定します。
sed
df -h | sed -n '1p; /^\/dev/p'
-n
は、通常の出力を抑制して、行が出力されないようにします。 1p
は最初の行を印刷することを意味し、/^\/dev/p
は/dev
で始まる行を印刷することを意味します。
以下のコメントで指摘されているように、現在のシステムのロケールによってヘッダー行が/dev
で始まるというまれなケースでは、上記のコマンドで2回出力されます。 Stephane Chazelas 指摘 これには問題がないこと:
df -h | sed -e 1b -e '/^\/dev/!d'
grep
df -h | grep -E '^(/dev|File)'
これは、あなたが言ったようにLOCALEの問題のために移植できないかもしれません。ただし、ロケールまたはdf
バージョンが最初の行にパスを与えないことは合理的に確実であるため、/
を含まない行の検索も機能するはずです。
df -h | grep -E '^[^/]*$|^/dev'
df出力を解析しようとして問題が発生します ですが、単純なケースでは、次のように機能する可能性があります
LC_ALL=C df -P | awk 'NR == 1 || /^\/dev/'
これも機能するはずです(ただし、テストされていません)。
df | (read a; echo "$a"; grep /dev)
または
df | (head -n 1; grep ^/dev)
df -h | tee >(head -1) >(sleep 0.5;grep ^/dev) > /dev/null;sleep 1.0
df | head -n 1; df | grep ^/dev
df | grep -n '' | grep -E '^1:|[^:]*:/dev' | sed 's/[^:]*://'
grep -n
ストリームに行番号を挿入します。次に、egrepを介して最初の行と対象の行を引き出し、sedを介して出力から追加した番号を削除します。
positive lookbehinds を使用することでsed
を回避できます(これはgrep
が [〜#〜] pcre [〜#〜]で処理できる =エンジン(-P
))および-o
は、一致したパターンのみを出力するようにgrep
に指示します。
df | grep -n '' | grep -Po '(?<=^1:)(.*)|(?<=:)(/dev.*)'
body
の定義を sortから取得しますが、ヘッダー行を先頭に保持します
# print the header (the first line of input)
# and then run the specified command on the body (the rest of the input)
# use it in a pipeline, e.g. ps | body grep somepattern
body() {
IFS= read -r header
printf '%s\n' "$header"
"$@"
}
このように使う
$ df -h | body grep ^/dev
Filesystem Size Used Avail Use% Mounted on
/dev/sda1 23G 6.1G 16G 29% /
/dev/sda6 890G 324G 521G 39% /home
/dev/sdb1 459G 267G 169G 62% /home/user/mnt
Df出力をフィルタリングする代わりに、その入力をフィルタリングできます。
前:
$ df -h
Filesystem Size Used Avail Use% Mounted on
C:/Cygwin/bin 150G 76G 74G 51% /usr/bin
C:/Cygwin/lib 150G 76G 74G 51% /usr/lib
C:/Cygwin 150G 76G 74G 51% /
C: 150G 76G 74G 51% /cygdrive/c
後:
$ mount | grep ^C:/Cygwin | cut -d' ' -f3 | xargs df -h
Filesystem Size Used Avail Use% Mounted on
C:/Cygwin/bin 150G 76G 74G 51% /usr/bin
C:/Cygwin/lib 150G 76G 74G 51% /usr/lib
C:/Cygwin 150G 76G 74G 51% /
PDATE 2014-01-24 08:03 UTC:行頭のC:/ Cygwinのgrepのみ