Понимание списка в чистом BASH? - PullRequest
4 голосов
/ 17 июля 2011

Возможно ли сделать LC как в python и других языках, но только с использованием конструкций BASH?

То, что я хотел бы сделать, например:

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
}

вместо использования кода, подобного этому:

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

Знаете ли вы какие-либо рецепты для моделирования LC, как это ??

Edit:

Более конкретный пример LC:

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

Какой самый питоновский способ сделать то же самое в bash?

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

Ответы [ 3 ]

12 голосов
/ 17 июля 2011

Цикл в подстановке команд выглядит как понимание списка, если вы щурились. Ваш второй пример может быть записан как:

M=$(for x in $S; do if [ $(( x % 2 )) == 0 ]; then echo $x; fi done)
5 голосов
/ 17 июля 2011

Вот полуобобщенный формат для выполнения эквивалента LC в bash с массивами:

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

Вот ваш второй пример в этом формате:

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

Вот еще один пример, с менее тривиальной «функцией», но без условного:

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' 
1 голос
/ 17 июля 2011

То, что вы описываете, не похоже на понимание списка ... Вы можете делать то, что вам нужно (использовать переменную для представления теста, который вы хотите выполнить), используя одинарные или двойные скобки.Как пример:

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
}
...