编辑:我仍然需要弄清楚如何删除找到的元素

编辑:我仍然需要弄清楚如何删除找到的元素

我有一个数组,其内容如下:

# echo "${ARRAY[@]}"
1=Napp Slice
4=NNN Issue
3=GG Allow
2=CO-OP
1=Quit

我想循环遍历它以查看是否有包含该单词的元素Quit,如果是,则将该元素设置为变量。所以我跑到下面:

for x in ${ARRAY[@]}; do
  if [ $x == *Quit* ]; then
    FOO=$x
    echo $FOO
  else
    break
  fi
done

我想返回给我,1=Quit 但是当我运行它时,我得到:

# ./myScript.ksh
1=Napp Slice
4=NNN Issue
3=GG Allow
2=CO-OP
1=Quit

我怎样才能拔出来只是Quit包含? 的元素

在发帖之前,我确实尝试过查看这个问题是否存在,我对 shell 脚本还不熟悉。我确信我遗漏了一些非常简单的东西,但我似乎无法理解。

请仅使用 KSH 语法,因为这是我可以使用的所有语法。

编辑:我仍然需要弄清楚如何删除找到的元素

谢谢你!

答案1

当我尝试使用 运行脚本时出现错误ksh93,主要是因为==[ ... ].我不清楚你使用的是什么外壳。break一旦与模式不匹配,您也会立即执行,这意味着您可能只运行循环的一次迭代。目前尚不清楚您的数组的输出是什么,但很可能不是您显示的代码。

无论如何,以下脚本在ksh93shell 中执行您想要的操作(并且在bash结果中,和zsh):

array=(
        '1=Napp Slice'
        '4=NNN Issue'
        '3=GG Allow'
        '2=CO-OP'
        '1=Quit'
)

for element in "${array[@]}"; do
        if [[ "$element" == *Quit* ]]; then
                foo=$element
                printf '%s\n' "$foo"
                break
        fi
done

[[ ... ]]请注意与模式匹配运算符一起使用==。另外,请小心引用 的扩展${array[@]},以便每个元素都单独引用,而不是按空格分割。

在注释中,您说要从数组中删除该元素。如果您循环遍历数组的元素,则无法执行此操作,但如果您迭代数组的索引,则可能会取消设置该元素。

for index in "${!array[@]}"; do
        if [[ "${array[index]}" == *Quit* ]]; then
                foo=${array[index]}
                unset -v 'array[index]'
                printf '%s\n' "$foo"
                break
        fi
done

请注意,这可能会为您提供一个在某处“丢失”元素的数组,并且数字索引不再是连续的。


下面的代码大致重现了上面第二个代码块的功能,但对于sh,添加了一些额外的功能。这里提供它纯粹是为了我们自己的娱乐。

#!/bin/sh

set --  '1=Napp Slice'  \
        '4=NNN Issue'   \
        '3=GG Allow'    \
        '2=CO-OP'       \
        '1=Quit'

unset -v found

for element do
        shift
        case $element in (*Quit*) found=$element; continue; esac
        set -- "$@" "$element"
done

printf 'Element = %s\n' "${found-(was not found)}"
printf 'Remaining list:\n'
printf '\t%s\n' "$@"

相关内容