erro variável no bash

4

Estou escrevendo meu primeiro código no bash. Estou preso de 2 horas. Este é o meu código:

#!/bin/bash
declare -i l=0
declare -i d=0
declare -i s1=0
declare -i s2=0
declare -i t=0
declare -i o=0
declare -i p=0
for i in demo_room/subject_1/?*
do
    if [ "${i:0:1}" = "l" ];
    then
            ((l++));
            echo "l=$l"
            python motempl_n.py $i $l

    elif [  "${i:0:1}" = "d" ];
    then
            ((d++));
            echo "d=$d"
            python motempl_n.py $i $d

    elif [  "${i:0:1}" = "o" ];
    then
            o=$((o+1));
            echo "o=$o"
            python motempl_n.py $i $o

    elif [ "${i:0:1}" = "p" ];
    then
            p=$((p+1));
            python motempl_n.py $i $p

    elif [  "${i:0:1}" = "t" ];
    then
            t=$((t+1));
            python motempl_n.py $i $t

    elif [  "${i:0:7}" = "slide_1" ];
    then
            s1=$((s1+1));
            python motempl_n.py $i $s1

    #elif [  "${i:0:7}" == 'slide_2' ]
    else
            s2=$((s2+1));
            python motempl_n.py $i $s2

   fi 
done

Então, estou tendo uma pasta demo_room/subject_1 . Nesta pasta eu tenho 140 vídeos avi seus nomes são:

20 vídeos têm nome: dislike_01 to dislike_20

20 vídeos têm nome: like_01 to like_20

20 vídeos têm nome: ok_01 to ok_20

20 vídeos têm nome: point_01 to point_20

20 vídeos têm nome: slide_1_01 to slide_1_20

20 vídeos têm nome: slide_2_01 to slide_2_20

20 vídeos têm nome: take_a_picture_01 to take_a_picture_1_20

O que eu quero fazer é primeiro encontrar a classe do vídeo de entrada e dar sua ocorrência como entrada para o arquivo python. Os primeiros 20 vídeos da pasta subject_1 são dislike one, então esse código funciona bem, mas o 21º vídeo é like_01 , mas o parâmetro que ele passa para o código python é 21.

Mas deve ser 1 porque este é o primeiro vídeo de uma classe semelhante no loop for. E cada vez que imprime valor de $d . Isso significa que cada vez que vai em 2 if condition . No código python, posso verificar se o nome do vídeo é like_01 , mas o segundo valor passado é 21 . Por quê? Isso acontece para todos os 140 vídeos.

    
por Debian_yadav 08.06.2018 / 15:36

3 respostas

8

Seu $i conterá o caminho completo ( demo_room/subject_1/file ), portanto, sempre começará com d .

Você pode fazer algo como:

case "${i##*/}" in
  (d*) ...;;
  (l*) ...;;
  (slide1_*) ...;;
  ...
esac

Em que ${i##*/} é $i com a parte principal correspondendo a */ removido.

Tenha também em atenção que as expansões de parâmetros precisam de ser citadas em sh / bash:

python motempl_n.py "$i" "$s2"
    
por 08.06.2018 / 15:45
7

Enquanto seu código está bem escrito, há muita duplicação. Aqui está uma versão mais condensada:

#!/bin/bash
declare -A count
for file in demo_room/subject_1/*; do
    base=${file##*/}
    case $base in
        slide_[12]*) key=${base:0:7};;
        [ldopt]*)    key=${base:0:1};;
        *)           ;; # other types ignored
    esac
    (( count[$key]++ ))
    echo "$key=${count[$key]}"
    python motempl_n.py "$file" "${count[$key]}"
done

Estou usando uma matriz associativa em vez de variáveis inteiras distintas, mas, felizmente, a aritmética bash manipula (( an_unset_variable++ )) normalmente e atribui "1" à variável.

Observe que ? no seu ?* foi redundante, pois os nomes de arquivo sempre contêm pelo menos um caractere, portanto, não há arquivos que * (0 ou mais caracteres) correspondam e ?* (1 ou mais personagens) não.

    
por 08.06.2018 / 17:09
1

Sua variável $i sempre começa com d : demo_room … …
Você precisa extrair o nome do arquivo. E como estamos extraindo, podemos também extrair o nome e o número do arquivo.

Assim, uma versão mais curta do seu script pode ser:

#!/bin/bash

declare -Ai count

for i in ./demo_room/subject_1/?*; do
    j=${i##*/} ; name=${j%_*} ; number=${j##*_}
    ((count[$name]++))
    echo \
           python motempl_n.py "$i" "${count[$name]}"
done

echo "List of keys: " "${!count[@]}"

Este script usa apenas uma variável de matriz count , a lista de chaves (automaticamente) usadas (de $name ) é impressa no final do script.

Comente a linha echo \ assim que você gostar de como o script funciona para realmente executar os comandos.

    
por 08.06.2018 / 22:40