有没有办法在循环数组时确定最后一个条目?从数组创建查找命令

有没有办法在循环数组时确定最后一个条目?从数组创建查找命令

我正在尝试使用数组中的条目创建查找命令选项字符串,但在数组的最后一个条目上我想添加不同的字符串。

EXT=(sh mkv txt)

EXT_OPTS=(-iname)

# Now build the find command from the array
for i in "${EXT[@]}"; do
    #echo $i
    EXT_OPTS+=( "*.$i" -o -iname)
done

干杯

编辑:

所以现在我要:

#!/bin/bash

EXT=(sh mkv txt)

EXT_OPTS=()
# Now build the find command from the array
for i in "${EXT[@]}"; do
    EXT_OPTS+=( -o -iname "*.$i" )
done

# remove the first thing in EXT_OPTS
EXT_OPTS=( "${EXT_OPTS[@]:1}" )

# Modify to add things to ignore:

EXT_OPTS=( "${EXT_OPTS[@]:-1}" )
EXT_OPTS=( '(' "${EXT_OPTS[@]}" ')' ! '(' -iname "*sample*" -o -iname "*test*" ')' )

#echo "${EXT_OPTS[@]}"

searchResults=$(find . -type f "${EXT_OPTS[@]}")

echo "$searchResults"

对我来说产生这个:

./Find2.sh
./untitled 2.sh
./countFiles.sh
./unrar.sh
./untitled 3.sh
./untitled 4.sh
./clearRAM.sh
./bash_test.sh
./Test_Log.txt
./untitled.txt
./Find.txt
./findTestscript.sh
./untitled.sh
./unrarTest.sh
./Test.sh
./Find.sh
./Test_Log copy.txt
./untitled 5.sh
./IF2.sh

答案1

以另一个顺序添加选项,然后删除第一个元素:

EXT=(sh mkv txt)

EXT_OPTS=()
# Now build the find command from the array
for i in "${EXT[@]}"; do
    EXT_OPTS+=( -o -iname "*.$i" )
done

# remove the first thing in EXT_OPTS
EXT_OPTS=( "${EXT_OPTS[@]:1}" )

如果你不使用$@任何东西,它看起来会更整洁:

EXT=(sh mkv txt)

# Empty $@
set --

# Now build the find command from the array
for i in "${EXT[@]}"; do
    set -- -o -iname "*.$i"
done

# remove the first thing in $@
shift

# assign to EXT_OPTS (this would be optional, you could just use "$@" later)
EXTS_OPTS=( "$@" )

我更喜欢添加-o -iname "*.$i"到中间数组,因为"*.$i" -o -iname很难阅读。添加到-o -iname "*.$i"$@可以使真的很容易就可以shift关闭第一个-o循环后的内容。


与一些排除项(要忽略的名称)结合使用:

extensions=( sh mkv txt )
ignore_patterns=( '*sample*' '*test*' )

include=()
# Now build the find command from the array
for ext in "${extensions[@]}"; do
    include+=( -o -iname "*.$ext" )
done

# Do the ignore list:
ignore=()
for pattern in "${ignore_patterns[@]}"; do
    ignore=( -o -iname "$pattern" )
done

# combine:
EXT_OPTS=( '(' "${include[@]:1}" ')' ! '(' "${ignore[@]:1}" ')' )

请注意添加的括号是为了区分测试的优先级。

答案2

最简单的方法是事后修复阵列。之后done,添加

unset 'EXT_OPTS[-1]'
unset 'EXT_OPTS[-1]'

将删除最后两个值(-o-iname),然后您可以根据需要添加其他值(或者直接替换它们)。

有可能轻微地只需添加一个冗余条件就更容易了:

EXT_OPTS+=( "*.${EXT[0]}" )

如果你的实际情况有点复杂,但对于这个,我只会按照上述方法修复它。

答案3

有没有办法在循环数组时确定最后一个条目?

只是按照字面意思回答这个问题,我认为你不能直接这样做。但是您当然可以在循环时对元素进行计数并将其与数组大小进行比较:

test=(foo bar blah qwerty)
count=${#test[@]}
n=1
for x in "${test[@]}"; do
   last=""
   if [[ $((n++)) -eq count ]]; then
        last=" (last)"            # last element, add a note about that
   fi
   printf "%s%s\n" "$x" "$last"
done

当然,根据您的情况,您也可以第一的项目是独一无二的。

相关内容