ファイルを含むデバイスをどのように検索してスクリプトで使用できますか?

ファイルを含むデバイスをどのように検索してスクリプトで使用できますか?

自分のファイルがどのデバイスにあるかを確認し、スクリプトで使用できるようにしたいと思います。私はこれを行うことができます:

$ df  .
Filesystem   512-blocks      Used Available Capacity  Mounted on
/dev/disk0s2  498438976 294369520 203557456    60%    /

しかし、この出力はあまりにも薄く見えます。 2行目の最初の「単語」を取得するために解析するよりも良い方法はありますか?

私にとって本当に必要なのは、次のコマンドでパイプできるようにすることです。

$ somecommand .
/dev/disk0s2

「df」出力で文字列ハッキングを使用せずにこれを達成するにはどうすればよいですか?

答え1

シェルのみを使用してこれを実行できます(bash、、、、に適用)。dashkshzsh

df . | (read a; read a b; echo "$a")

あるいは、出力を必要とせず(結果は$ aに格納されています)、シェルがプロセス置換をサポートしている場合(例えば、、bashzsh

{ read; read a b;}< <(df .)

以下は、他のソリューションの速度とのいくつかの比較です。

# pure shell solution 1

bash-4.2$ time for i in $(seq 500); do df . | (read a; read a b; echo "$a"); done > /dev/null
1.899

(dash) $ time -f '%e' dash -c 'for i in $(seq 500); do df . | (read a; read a b; echo "$a"); done > /dev/null'
1.05

(ksh) $ time for i in $(seq 500); do df . | (read a; read a b; echo "$a"); done > /dev/null
    0m1.16s real     0m0.02s user     0m0.12s system

(zsh) manatwork% time (for i in $(seq 500); do df . | (read a; read a b; echo "$a"); done > /dev/null)
1.51s

# pure shell solution 2

bash-4.2$ time for i in $(seq 500); do { read; read a b;}< <(df .); done
1.192

(zsh) manatwork% time (for i in $(seq 500); do { read; read a b;}< <(df .); done)
3.51s

# other solutions

bash-4.2$ time for i in $(seq 500); do df . | tail -1 | cut -f 1 -d " "; done > /dev/null
1.405

bash-4.2$ time for i in $(seq 500); do df . | sed '2!d' | awk '{print $1}'; done > /dev/null
5.407

bash-4.2$ time for i in $(seq 500); do df . | sed -n '2{s/ .*$//;p}'; done > /dev/null
1.767

bash-4.2$ time for i in $(seq 500); do df . | sed '2!d' | awk '{print $1}'; done > /dev/null
3.334

bash-4.2$ time for i in $(seq 500); do df . | gawk 'NR==2{print $1}'; done > /dev/null
3.013

bash-4.2$ time for i in $(seq 500); do df . | mawk 'NR==2{print $1}'; done > /dev/null
1.747

bash-4.2$ time for i in $(seq 500); do df . | perl -nae 'print$F[0]if$.==2'; done > /dev/null
2.752

statここでは動作しないため、ソリューションと比較されません。)

答え2

これは一般的にそうですUNIXでの方法簡単なプログラムの機能をビット単位で接続します。したがって、df一部のフィルタを介して出力を渡すことを心配しないでください。

df /path/to/file | sed -n '2{s/ .*$//;p}'

-n自動的に印刷行を抑制し、2{}2行目に含まれているコマンドを実行し、s/ .*$//最初の空白の内容をすべて捨て、p残りを印刷します。長い入力を解析し、2番目(またはn番目)の行だけを必要な状況でq追加すると、p作業速度が速くなる可能性があります。

答え3

sed次の簡単な1行を使用awkできます。

df . | sed '2!d' | awk '{print $1}'

sed指定することは、2d2番目の行を削除することを意味します。!他のすべての行を削除し、2行目を印刷するように否定を追加します。その後、コマンドはawk値の最初の列を表示します。

出力:

/dev/disk0s2

答え4

Linuxを使用している場合findmntutil-linuxパッケージの一部)を使用できます。「文字列ハッキングに頼る必要はありません」:

findmnt -no source -T /path/to/file
/dev/sda1

このオプションを使用する場合

-T、-ターゲット
パスがマウントポイントファイルまたはディレクトリでない場合は、マウントfindmntポイントを取得するためにパス要素を逆の順序で確認します。他の2つのオプションはヘッダー行を抑制し、一覧-n, --noheading表示する列を選択します。-o, --output


dffromには、特定のフィールドのみを印刷するcoreutils同様のオプションがあります。たとえば、次のようになります。--output=source

df --output=source /path/to/file
ファイルシステム
/dev/sda1

ただし、タイトルを削除するオプションはありません。これが問題である場合は、最小限の措置を講じる必要があります。文字列ハッカーたとえば、パイプとしてsed 1d

関連情報