开发者

List comprehension in pure BASH?

开发者 https://www.devze.com 2023-03-21 06:18 出处:网络
Is it possible to do LC like in python and other languages bu开发者_Python百科t only using BASH constructs?

Is it possible to do LC like in python and other languages bu开发者_Python百科t only using BASH constructs?

What I would like to be able to do, as an example is this:

function ignoreSpecialFiles()
{
    for options in "-L" "-e" "-b" "-c" "-p" "-S" "! -r" "! -w"; do
        if [[ $options "$1" -o $options "$2" ]];then
            return $IGNORED
        fi
    done
}

instead of using code like this:

if [[ -L "$1" -o -e "$1" -o -b "$1" -o -c "$1" -o -p "$1" -o -S "$1" -o\
! -r "$1" -o ! -w "$1" ]]

Do you know of any recipes for simulating LC like this??

Edit:

A more LC specific example:

M = [x for x in S if x % 2 == 0] #is python

what is the most pythonic way to do the same in bash?

for x in S; do if x % 2 == 0;then (HERE MY HEAD EXPLODES) fi done


A loop in a command substitution looks like a list comprehension if you squint. Your second example could be written as:

M=$(for x in $S; do if [ $(( x % 2 )) == 0 ]; then echo $x; fi done)


Here's a semi-general format for doing the equivalent of LC in bash with arrays:

outarray=()
for x in "${inarray[@]}"; do
    if SOMECONDITION; then
        outarray+=(SOMEFUNCTIONOFx)
    fi
done

Here's your second example in this format:

s=({1..10})
echo "${s[@]}"
# Prints: 1 2 3 4 5 6 7 8 9 10
m=()
for x in "${s[@]}"; do
    if (( x % 2 == 0 )); then
        m+=($x)
    fi
done
echo "${m[@]}"
# Prints: 2 4 6 8 10

Here's another example, with a less trivial "function" but without the conditional:

paths=("/path/to/file 1" "/path/somewhere/else" "/this/that/the other" "/here/there/everywhere")
filenames=()
for x in "${paths[@]}"; do
    filenames+=( "$(basename "$x")" )
done
printf "'%s' " "${filenames[@]}"
# Prints: 'file 1' 'else' 'the other' 'everywhere' 


What you're describing doesn't look like list comprehensions... You can do what it looks like you want (use a variable to represent the test that you want to perform) using single brackets instead of double brackets. As an example:

function ignoreSpecialFiles()
{
    for options in "-L" "-e" "-b" "-c" "-p" "-S" "! -r" "! -w"; do
        if [ $options "$1" -o $options "$2" ]
        then
            return $IGNORED
        fi
    done
}
0

精彩评论

暂无评论...
验证码 换一张
取 消