从构造的带有空格的字符串列表中选择?

j4n*_*53n 2 bash select

我尝试创建一个包含空格的字符串列表,我想在其中进行选择select- 如下所示:

sel=""
while read l   
do
  sel=$(printf "%s '%s'" "$sel" "$l")
done< <(cd /some/data/directory;du -sh *) 

select x in $sel
do
  break
done
Run Code Online (Sandbox Code Playgroud)

该字符串sel看起来像预期的:"597G 2022" "49G analysis" "25K @Recycle",但选择看起来像:

1) "597G      3) "49G       5) "25K
2) 2022"      4) analysis"  6) @Recycle"
#?
Run Code Online (Sandbox Code Playgroud)

我想要实现的目标当然是:

1) 597G 2022
2) 49G  analysis
3) 25K  @Recycle
#?
Run Code Online (Sandbox Code Playgroud)

更一般地说,您可以在以某种方式从多个数据源构建的字符串之间进行选择。我在几个地方寻找灵感,比如这里,但它不太适合我的情况。

编辑

我忘了提,这个 bash 相当旧了(遗憾的是我无法更新它):

[admin@CoMind-UniCron ~]# bash --version
GNU bash, version 3.2.57(1)-release (x86_64-QNAP-linux-gnu)
Copyright (C) 2007 Free Software Foundation, Inc.
Run Code Online (Sandbox Code Playgroud)

ter*_*don 5

您想要在那里使用多个字符串的数组,而不是必须由 shell 正确分割的单个字符串。像这样的东西:

#!/bin/bash

while read l   
do
  sel+=( "$l" )
done< <(cd /some/data/directory;du -sh *) 

select x in "${sel[@]}"
do
  break
done
Run Code Online (Sandbox Code Playgroud)

这会产生预期的输出:

$ foo.sh
1) 597G 2022
2) 50G  analysis
3) 32K  @Recycle
#? 
Run Code Online (Sandbox Code Playgroud)

一种更安全的方法,可以处理除换行符之外的任意文件/目录名称,并且只是稍微复杂一点,但可以在所有情况下使用而无需担心:

#!/bin/bash

while IFS= read -r l   
do
  sel+=( "$l" )
done< <(shopt -s nullglob dotglob; cd /some/data/directory && du -sh -- *) 

select x in "${sel[@]}"
do
  break
done
Run Code Online (Sandbox Code Playgroud)

  • Bash 3.2 支持数组,因此用于添加到数组的赋值运算符“+=”也应该支持。 (2认同)
  • @terdon,数组是在 2.0 中添加到 bash 中的,比 zsh 晚了几年,比 csh 或 ksh 晚了几十年,但仍然是 25 年前。+=(最初来自 zsh IIRC)在 3.1 中添加 (2认同)