在 bash 中使用新变量重新启动 Select 循环

发布于 2024-12-16 17:23:11 字数 800 浏览 1 评论 0原文

我试图在更改其中的变量后重新启动选择循环,目前它会增加所有内容,但它不会重新运行选择循环。这是我的代码:

select listfile in "${FILEARRAY[@]:$START:$FINISH}" Next
do
    if [[ $listfile == "Next" ]];then
        echo "Check point 1 $START and $FINISH"
        if [[ ${#FILEARRAY[@]} > $FINISH ]];then
            START=$(($START + 23))
            FINISH=$(($FINISH + 23))
            echo "Check point 2 $START and $FINISH"
        elif [[ ${#FILEARRAY[@]} < $FINISH || ${#FILEARRAY[@]} == $FINISH ]];then
            echo "No more files"
            exit
        fi
    else
        FILE=$listfile
        break
    fi
done    

我在检查点 1 和 2 中编辑,检查点 1 给我 0 和 23 (就像它应该的那样),检查点 2 给我 23 和 46 (也像它应该的那样)。在它递增之后,我希望它重新启动选择,但使用数组中的位置 23 到 46。

编辑2:该数组仅包含文件名:

FILEARRAY=( $(ls) )

I'm trying to restart the select loop after I change the variables inside of it, currently it increments everything, but it does not rerun the select loop. Here is my code:

select listfile in "${FILEARRAY[@]:$START:$FINISH}" Next
do
    if [[ $listfile == "Next" ]];then
        echo "Check point 1 $START and $FINISH"
        if [[ ${#FILEARRAY[@]} > $FINISH ]];then
            START=$(($START + 23))
            FINISH=$(($FINISH + 23))
            echo "Check point 2 $START and $FINISH"
        elif [[ ${#FILEARRAY[@]} < $FINISH || ${#FILEARRAY[@]} == $FINISH ]];then
            echo "No more files"
            exit
        fi
    else
        FILE=$listfile
        break
    fi
done    

I edited in check point 1 and 2, check point 1 gives me 0 and 23 (like it should) and check point 2 give me 23 and 46 (also like it should). After it increments I want it to restart the select but using position 23 through 46 from the array.

Edit 2: The array just contains names of files:

FILEARRAY=( $(ls) )

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

旧故 2024-12-23 17:23:11

我也不明白这个问题,但根据你的评论,我“认为”我知道你想做什么,但我仍然不知道你为什么要这样做。

无论如何,让我向您解释一些事情,首先 select 本身并没有获得变量,它获得的是扩展结果,因为 shell 在命令看到它之前替换了它,所以,如果您想在每个切片上执行不同的 select ,您需要从外部循环并每次使用新参数重新运行 select 语句。

我会做这样的事情:

#!/bin/bash

pagesize=23

filearray=(*)
start=0
while true; do
    pagefiles=("${filearray[@]:$start:$pagesize}")
    ((start > 0)) && pagefiles=(Prev "${pagefiles[@]}")
    ((start+pagesize < ${#filearray[@]})) && pagefiles=("${pagefiles[@]}" Next)
    select listfile in "${pagefiles[@]}"; do
        case $listfile in
        Prev)
            start=$((start-pagesize));;
        Next)
            start=$((start+pagesize));;
        *)
            filename=$listfile
        esac
        break
    done
    [[ $filename ]] && break
done

echo "$filename"

注意 bash 中的数组切片表示法不采用开始结束,而是采用开始长度。

另外,这一点非常重要,永远不要解析或重用 ls 的输出(请参阅 http://mywiki.wooledge.org/ParsingLs)如果您想要数组中目录中的所有文件,只需执行 FILEARRAY=(*) 即可安全存储。

I didn't understand the question either, but according to your comments I "think" I know what you're trying to do but still I've no idea WHY you would do that.

in any case let me explain you a few things, first of all the select isn't getting a variable per se, what it gets is the expanded result because the shell replaces that before the command sees it so, if you want to perform different select on each slice you need to loop from the outside and rerun the select statement with the new arguments every time.

I would do something like this:

#!/bin/bash

pagesize=23

filearray=(*)
start=0
while true; do
    pagefiles=("${filearray[@]:$start:$pagesize}")
    ((start > 0)) && pagefiles=(Prev "${pagefiles[@]}")
    ((start+pagesize < ${#filearray[@]})) && pagefiles=("${pagefiles[@]}" Next)
    select listfile in "${pagefiles[@]}"; do
        case $listfile in
        Prev)
            start=$((start-pagesize));;
        Next)
            start=$((start+pagesize));;
        *)
            filename=$listfile
        esac
        break
    done
    [[ $filename ]] && break
done

echo "$filename"

notice the array slice notation in bash doesn't take start-end it takes start-length.

also, and this is VERY important, don't EVER parse or reuse the output of ls (see http://mywiki.wooledge.org/ParsingLs) if you want all the files in the directory on an array just do FILEARRAY=(*) and it'll be safely stored.

柏林苍穹下 2024-12-23 17:23:11
   STEP=23
   START=0
   FINISH=$STEP
   FILEARRAY=( $(ls) )


   function slct {
       START=$1
       STEP=$2
       FINISH=$3


       select listfile in "${FILEARRAY[@]:$START:$STEP}" Next
       do
           if [[ $listfile == "Next" ]];then
               echo "Check point 1 $START and $FINISH"
               if [[ ${#FILEARRAY[@]} -gt $FINISH ]];then
               echo ${#FILEARRAY[@]}   FA
               echo $FINISH FIN
                   START=$((START + STEP))
                   FINISH=$((FINISH + STEP))
                   slct $START $STEP $FINISH
                   break;
               echo "Check point 2 $START and $FINISH"

               elif [[ ${#FILEARRAY[@]} < $FINISH || ${#FILEARRAY[@]} == $FINISH ]];then
                   echo "No more files"
                   exit
               fi
           else
               FILE=$listfile
               echo SELECTED $listfile
               break
           fi
       done
   }

   slct 0 $STEP $STEP
   STEP=23
   START=0
   FINISH=$STEP
   FILEARRAY=( $(ls) )


   function slct {
       START=$1
       STEP=$2
       FINISH=$3


       select listfile in "${FILEARRAY[@]:$START:$STEP}" Next
       do
           if [[ $listfile == "Next" ]];then
               echo "Check point 1 $START and $FINISH"
               if [[ ${#FILEARRAY[@]} -gt $FINISH ]];then
               echo ${#FILEARRAY[@]}   FA
               echo $FINISH FIN
                   START=$((START + STEP))
                   FINISH=$((FINISH + STEP))
                   slct $START $STEP $FINISH
                   break;
               echo "Check point 2 $START and $FINISH"

               elif [[ ${#FILEARRAY[@]} < $FINISH || ${#FILEARRAY[@]} == $FINISH ]];then
                   echo "No more files"
                   exit
               fi
           else
               FILE=$listfile
               echo SELECTED $listfile
               break
           fi
       done
   }

   slct 0 $STEP $STEP
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文