在定义的目录范围内执行命令

Joe*_*ley 5 ls bash indexing

是否可以对目录列表进行“分区” - 说成一些数量的块,以对每个“范围”执行不同的操作?

例如,假设我在另一个文件夹中有以下目录:

$ ls test
abc/
def/
hij/
klm/
nop/
qrs/
tuv/
wxy/
zzz/
Run Code Online (Sandbox Code Playgroud)

我想对前 3 个目录执行一些操作,对第二个 3 执行另一个操作,依此类推。

我的想法是,基于类似的输出,跨数字循环可能会起作用ls | nl(但在任何人提到它之前,我知道解析ls是禁忌!)

这显然不起作用,但说明了我希望的观点:

for dir in `ls | nl`; 
do
    do-something-with ${dir{1..3}} # Where $dir has taken on some numerical value linked to the folder)
    do-something-with ${dir{4..6}} 
# And so on...
    do-something-with ${dir{n-3..n}} 
done
Run Code Online (Sandbox Code Playgroud)

我打算实际执行此操作的文件夹可以按任何顺序处理(即最终拆分可以完全任意),但它们没有逻辑命名一致性 - 我的意思是它们不能按字母顺序或数字顺序进行合理组织基于目录名称本身中的任何键。

Wil*_*ard 3

对于这种情况,没有理由犯以下任何错误:

  1. 使用不可移植的 GNU 扩展(例如xargs -0
  2. 仅将文件名解析为文本流,假装它们不能包含换行符。

您可以毫无困难地轻松处理此问题:

set -- */
while [ "$#" -gt 0 ]; do
  case "$#" in
    1)
      my-command "$1"
      shift 1
      ;;
    2)
      my-command "$1" "$2"
      shift 2
      ;;
    *)
      my-command "$1" "$2" "$3"
      shift 3
      ;;
  esac
done
Run Code Online (Sandbox Code Playgroud)

实际上,这比必要的更冗长,但这样是可读的。

对于不同类型的分区,您想要将所有目录拆分为三种不同的处理方法(但不需要同时处理它们),您可以这样做:

x=1
for d in *; do
  [ ! -d "$d" ] && continue
  case "$x" in
    1)
      # do stuff with "$d"
      ;;
    2)
      # do stuff with "$d"
      ;;
    3)
      # do stuff with "$d"
      ;;
  esac
  x=$(($x+1))
  [ "$x" -eq 4 ] && x=1
done
Run Code Online (Sandbox Code Playgroud)