como faço para extrair o nome SubDir 4 deep & colocar em um Var 4 uso posterior?

0

Eu preciso saber como colocar o quarto nome do diretório na árvore. este diretório var altera enquanto trabalha através dele usando um loop, então enquanto o loop está em execução sempre atualizando este diretório structor eu preciso atualizar isso e mantê-lo atualizado

/ dir 1 / dir 2 / dir 3 / dir 4 / dir 5 / Eu só preciso pegar o nome que está nesse diretório em um var para usá-lo em outro lugar

Estou usando um loop e uma extração como essa.

#!/bin/bash

working_dir="/media/data/temp1"

script_dir="$HOME/working"

find "$working_dir" -type f -name "*.*" | while [ $xf  -lt $numberToConvert ] ; 
do read FILENAME;

j=$FILENAME
xpath=${j%/*} 
xbase=${j##*/}
xfext=${xbase##*.}
xpref=${xbase%.*}
path1=${xpath}

pref1=${xpref}
ext1=${xfext}
echo 
echo
echo "xpath is -> "$xpath""
echo "xbase is -> "xbase""
echo "xfext is -> "$xfext""
echo "xpref is -> "$xpref""
echo "path is -> "$path1""
echo "pref is -> "$pref1""
echo "ext is -> "$ext1""
echo
getme="$(basename "$working_dir/")" 
echo "GET ME "$getme""
echo

  //Code that does stuff to files in dir's after the 4th Dir
  // is here but hidden 

let xf++
done

a saída para tudo isso é:

xpath is -> /media/data/temp1/Joe Jackson - The Ultimate Collection/CD2
xbase is -> xbase
xfext is -> mp3
xpref is -> Jumpin' Jive Live - Joe Jackson
path is -> /media/data/temp1/Joe Jackson - The Ultimate Collection/CD2
pref is -> Jumpin' Jive Live - Joe Jackson
ext is -> mp3

GET ME temp1

basename retorna o terceiro diretório não o 4º depois daquele, é isso que eu preciso para obter o nome do entre / temp1 / ... / e CD

/media/data/temp1/Joe Jackson - The Ultimate Collection/CD2

que o nome do Joe Jackson ... dir mudará quando o script terminar com ele, indo para outro diretório com um nome diferente, então eu preciso ser capaz de atualizá-lo e continuar recebendo apenas o nome do quarto.

tudo que eu preciso é que essa linha seja algo assim

    4thDirNameIs=${code goes here}

é 4 deep no diretório structor não 5 ou 3 ou qualquer outro dir ou nome do arquivo mesmo.

em que o título diz tudo é a palavra-chave, é preciso estar fora do directório para entrar no 4º nome do diretório nos diretórios.

Espero que esteja claro o suficiente desta vez

    
por uxserx-bw 20.11.2015 / 17:14

4 respostas

2

Se o seu arquivo for salvo como $FILENAME , todos darão o 4º diretório. Nestes exemplos, estou configurando manualmente

FILENAME="/media/data/temp1/Joe Jackson - The Ultimate Collection/CD2/Jumpin' Jive Live - Joe Jackson.mp3"
  • Use o shell:

    $ dir=${FILENAME#*/*/*/*/}; echo ${dir//\/*}
    Joe Jackson - The Ultimate Collection
    

    Aqui, primeiro removo as primeiras quatro barras, deixando o quarto diretório e o nome do arquivo e, em seguida, removendo o nome do arquivo.

  • Shell e basename :

    $ dir=${FILENAME#*/*/*/*/}; basename "$dir"
    Jumpin' Jive Live - Joe Jackson.mp3
    

    A mesma ideia acima, apenas usando basename para a etapa final.

  • Analise com Perl:

    $ echo "$ FILENAME" | perl -pe 's # (. ? /) {4} (. ?) /.*#$ 2 #' Joe Jackson - The Ultimate Collection

    A expressão regular corresponde a 4 repetições de 0 ou mais caracteres seguidos por uma barra, depois tudo para a próxima barra e depois para todo o resto. Os parênteses permitem que você capture um padrão correspondente, então estamos substituindo tudo pelo segundo padrão criado, o nome do diretório.

    Como alternativa, você pode dividir a linha em um array em slases e imprimir o 5º campo (5 porque o primeiro está vazio devido ao / no início da variável):

    $ echo "$FILENAME" | perl -F"/" -lane 'print $F[4]'
    Joe Jackson - The Ultimate Collection
    
  • Analise com awk :

    $ echo "$FILENAME" | awk -F"/" '{print $5}'
    Joe Jackson - The Ultimate Collection
    

    Mesma ideia, mas em awk .

por 20.11.2015 / 18:49
0

Você pode tentar usar os argumentos mindepth e maxdepth para localizar e canalizar isso para awk.

find $someBaseDir -type d -mindepth 4 -maxdepth 4 | awk -F'/' '{ print $NF }'

Se você quiser fazer algo para cada resultado, pode colocá-lo em um loop:

Talvez algo como:

for fdir in $(find $Base -type d -mindepth 4 -maxdepth 4 | awk -F'/' '{ print $NF }'); do DO_STUFF_WITH $fdir done

    
por 20.11.2015 / 22:48
0

A resposta de Jong está realmente próxima, mas os argumentos mindepth e maxdepth são relativos ao diretório inicial do comando find . Você também pode considerar o fato de que você já tem as três primeiras partes da estrutura de diretórios necessárias. Trabalhando a partir desse ponto, você realmente precisa apenas de um nível mais profundo para obter as informações que procura. Isso tem a vantagem de excluir tudo o mais no diretório exceto para as coisas que você deseja. O snippet a seguir usa sua variável predefinida $working_dir , os argumentos -mindepth e -maxdepth para find e expansão de parâmetro para localizar todos os diretórios na posição "4 deep" em / media / data / temp1:

for my_dir in $(find ${working_dir} -mindepth 1 -maxdepth 1 -type d -print)
    do
    DirName=${my_dir##${working_dir}/}
    ## loop through, working on the 4th directory list
    ## one directory at a time
    . . .
done

E FWIW, você não deve iniciar nomes de variáveis com um número. Algumas shells (como BASH) interpolarão essas como referências a parâmetros posicionais e não farão o que você espera (por exemplo, $4thDirNameIs será expandido para o parâmetro posicional $4 , que pode ou não existir, seguido por 'thDirNameIs' ).

    
por 23.11.2015 / 23:49
0

Obrigado a todos nesta pergunta que me ajudou, esta é a resposta que eu encontrei, ela encontra todos os dir que são o 4º dir na raiz da pasta dir / entao entra em um dir de cada vez pega todos os arquivos e trabalha sobre eles dentro do loop mais interno. depois que todos os arquivos selecionados são completados, ele se move para a próxima quarta posição do basedir e seu subdir então faz o mesmo

controlado pela entrada do usuário em quantos dir ele deseja que ele funcione e onde

#!/bin/bash

typeset -i f d control DirCountDn fileCount dirCount
let f=0 d=0 control=1  DirCountDn=0 fileCount=0 dirCount=0

amount_of_dir_to_work_on="4"

working_dir="/media/data/music"


   #CONTROL LOOP keeps it one dir at a time
        for i in 1
        do
            # get all of the names of the base dir to change name  a var containing ampunt of basenamedir in last place here 
            find "$working_dir" -mindepth 1 -maxdepth 1 -type d | while [ $DirCountDn  -lt $amount_of_dir_to_work_on ] ; 
                do read DIRNAME;
                    echo "$DIRNAME"
                    echo
                    MAXMP3="$(find "$DIRNAME" -type f -name "*.mp3" | wc -l)"
                    echo;echo;echo
                    echo "amount of mp3 "$MAXMP3" in "$DIRNAME""
                    echo;echo;echo;echo
                        find "$DIRNAME" -type f -name "*.mp3" | while [ $fileCount -lt $MAXMP3 ] ;
                        do read FILENAME;
                            echo;echo
                            echo "***************************************"
                            echo "FILENAME is "$FILENAME""
                            DIRNAME=${DIRNAME#*/*/*/*/} 
                            DIRNAME=${DIRNAME//\/*}
                            echo "DIRNAME is "$DIRNAME""
                            echo
                            echo " work each mp3 file in incurments until Dir is finised will all mp3 files" 
                            echo "rename dir then make provisons to move it somewhere else"
                            echo "then move it - go onto nest directory within the tree root dir"
                            echo "amount of filename "$fileCount""
                            echo "******************************************"
                            let fileCount++
                            echo "count on file names "$fileCount""
                            echo;echo

                        done
                let dirCount++
                echo "Dir Count "$dirCount""
                echo;echo
                let DirCountDn++

                #reset fileCount for next dir
                let fileCount=0
                done

                echo "this is i -> "$i""
        done

 # returns sub dir only one deep and not working dir
#find /dir/dir/dir/getThisOneNameOnly  -mindepth 1 -maxdepth 1  -type d   -exec basename {} \;
    
por 24.11.2015 / 18:36