我想找出我的文件所在的设备,以便我可以在脚本中使用它。我能做到这一点:
$ df .
Filesystem 512-blocks Used Available Capacity Mounted on
/dev/disk0s2 498438976 294369520 203557456 60% /
但这个输出感觉太笨拙了;有没有比解析它来获取第二行的第一个“单词”更好的方法?
我真正需要的是这样的东西,这样我就可以将它传送到下一个命令:
$ somecommand .
/dev/disk0s2
我怎样才能实现这一点,最好不诉诸字符串破解“df”输出?
答案1
您可以单独使用 shell 来完成此操作(适用于bash
、dash
、ksh
、zsh
):
df . | (read a; read a b; echo "$a")
或者,如果不需要输出(结果将保存在 $a 中)并且您的 shell 支持进程替换(如bash
, zsh
):
{ 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{}
执行第二行中包含的命令,s/ .*$//
丢弃第一个空格中的所有内容,p
打印剩下的内容。在解析较长输入并且只想要第二行(或第 n 行)的情况q
下添加p
也可以加快速度。
答案3
您可以使用简单的一行sed
,awk
如
df . | sed '2!d' | awk '{print $1}'
在 中sed
,指定2d
意味着删除第二行。添加一个!
否定,所以它只是删除所有其他行,并打印第二行。然后该awk
命令显示第一列值。
输出:
/dev/disk0s2
答案4
如果你使用的是linux,你可以使用findmnt
(util-linux
包的一部分)“无需诉诸字符串黑客”:
findmnt -no source -T /path/to/file
/dev/sda1
使用该选项时
-T,--目标小路如果路径不是挂载点文件或目录,
findmnt
则按相反顺序检查路径元素以获取挂载点。其他两个选项抑制标题行:-n, --noheading
并选择要列出的列:-o, --output
df
fromcoreutils
有一个类似的选项,--output=
可以仅打印某些字段,例如source
:
df --output=source /path/to/file
文件系统 /dev/sda1
但没有删除标题的选项。如果这是一个问题,你必须做一些最小的事情字符串黑客例如通过管道将其传输到sed 1d