为什么我无法使用 ${xx%% *} 从“du”命令的输出中提取第一个单词(大小)?

为什么我无法使用 ${xx%% *} 从“du”命令的输出中提取第一个单词(大小)?

我只是想编写一个脚本并需要提取目录的大小。在那里我发现了一个我不明白的奇怪效果:

我使用了“du”命令:

> x=$(du mydir)
> echo $x
8192 mydir

到目前为止还可以。但现在我想通过删除所有字符来提取大小X从第一个空格开始。但后来我明白了

> echo ${x%% *}
8192 mydir

而不仅仅是 8192。

所以用另一个变量检查​​了它,不是由“du”生成的

> y="8192 mydir"
> echo ${y%% *}
8192

为什么这适用于y但不是为了X?我还检查了Xy是相同的字符串。

我真的很困惑这里。如果有人能回答这个问题,我会很高兴?

答案1

如果你用双引号你的变量,你会发现明显有多个空格。事实上,它是一个制表符,您可以在某些系统上更清楚地看到它

echo "$x" | cat -e

因此,您可以将制表符(或空格)与此结构相匹配,从而删除最长的序列“空格或制表符后跟任何内容“ 绑定到字符串值的末尾$x

echo "${x%%[[:blank:]]*}"

答案2

xxd或者hd是调查此类事情的好工具。例子:

$ du sample
32  sample

$ du sample | xxd -g 1
00000000: 33 32 09 73 61 6d 70 6c 65 0a        32.sample.

如果你的十六进制表示法生锈了,你可以使用ascii

$ ascii -x
   00 NUL    10 DLE    20      30 0    40 @    50 P    60 `    70 p 
   01 SOH    11 DC1    21 !    31 1    41 A    51 Q    61 a    71 q 
   02 STX    12 DC2    22 "    32 2    42 B    52 R    62 b    72 r 
   03 ETX    13 DC3    23 #    33 3    43 C    53 S    63 c    73 s 
   04 EOT    14 DC4    24 $    34 4    44 D    54 T    64 d    74 t 
   05 ENQ    15 NAK    25 %    35 5    45 E    55 U    65 e    75 u 
   06 ACK    16 SYN    26 &    36 6    46 F    56 V    66 f    76 v 
   07 BEL    17 ETB    27 '    37 7    47 G    57 W    67 g    77 w 
   08 BS     18 CAN    28 (    38 8    48 H    58 X    68 h    78 x 
   09 HT     19 EM     29 )    39 9    49 I    59 Y    69 i    79 y 
   0A LF     1A SUB    2A *    3A :    4A J    5A Z    6A j    7A z 
   0B VT     1B ESC    2B +    3B ;    4B K    5B [    6B k    7B { 
   0C FF     1C FS     2C ,    3C <    4C L    5C \    6C l    7C | 
   0D CR     1D GS     2D -    3D =    4D M    5D ]    6D m    7D } 
   0E SO     1E RS     2E .    3E >    4E N    5E ^    6E n    7E ~ 

由此你很快就会发现:

  • 33 => 3
  • 32 => 2
  • 09 => HT,或水平制表符
  • 73 => s
  • ...

换句话说。32<HT>sample。空间是 0x20,33 32 20 73 ...如果是这样的话你就会得到。

另一个工具是od,这里使用-c选项(-a或者-ac也可以很好):

$ printf %s "$x" | od -c
0000000   3   2  \t   s   a   m   p   l   e

当您正确引用时,它还会为您提供实际内容。

解决方案是使用@roaimas 的例子或类似的东西

$ read -r size name<<< $(du sample)
$ echo "$size"
32

一切都取决于你想要什么awk也可能是一个不错的候选人。

相关内容