Bash, padrão de pesquisa no nome do arquivo e compará-lo

0

Estou tentando mover o arquivo com base no padrão via Bash Script.

Eu uso o Find para selecionar todos os arquivos da minha filmadora e o resultado do estoque no arquivo TXT.

Cada arquivo da minha filmadora contém a localização do ano, eu gostaria de usar o Grep ou algo assim para encontrar essa string (ano em 4 digitos ie 1984) e comparar esta string para mover o arquivo na pasta diferente, se o arquivo for depois de 1984 meu arquivo deve ir na pasta "Marie", se o arquivo for anterior ou igual a 1984 ele deve ir para a pasta "Marie_Liam".

Eu tentei várias coisas, com Grep e while read -r line, mas quando comparo found string (year) meu script retorna toda vez depois de 1984 ...

Aqui está minha tentativa diferente:

Eu tentei várias coisas como esta (é muita tentativa, não apenas um script):

Script base:

#!/bin/bash
find /home/CamFiles/ -name "*.m2ts"

Tente 1:

TestScriptResultFile="/home/Dio/CamCorderFindResult.file"
do
  if [ grep -e " 1984 " "$in" ];
  then
    echo "Voici un film qui est avant 1984 $FindMovie"
  else
    echo "Voici un film qui est de 1984 : $FindMovie"
  fi;
done

- Outra tentativa -

while IFS= read -r line; do
  if [[ /bin/grep -E "[1][9][8][4]" "$MyLine" != 0 ]] ;
  then
    echo "Ok"
  fi
done < "$TestScriptResultFile"
while read line; do
  if  echo "$line" | grep -q "[1][9][8][4]"; then echo "$line"; fi
  Found=$(echo "$line" | grep -q "[1][9][0-8][0-4]")
  if [[ " $Found " <= 1984 ]]; then echo "$line"; fi
done < "$TestScriptResultFile"
exit 0

- Outra tentativa -

while read MyLine
do
  if grep -E "$MyPattern" "$MyLine"
  then
    echo "tourne apres 1984 : $MyLine"
  else
    echo "Tourne avant 1984 : $MyLine"
  fi
done < "$TestScriptResultFile"

Obrigado pela sua ajuda.

Atenciosamente.

    
por Dio 13.09.2016 / 18:09

1 resposta

0

Atualizei os scripts com base nos exemplos de nome de arquivo que você forneceu em seu comentário:

"Liam sur la moto (VHS) (2001) - Maison 13100.m2ts" 
"M&L Plage 1080i (2012) - Camargue 30240.m2ts

Eu criei dois métodos para lidar com essa convenção de nomenclatura.

O primeiro é assumir que, em todos os casos, o ano está entre parênteses. Eu atualizei o script 'primeiro' para refletir esse caso; é simplesmente uma atualização para o padrão regex usado.

regexPat='\(\K[0-9]{4,4}(?=\))'

O segundo script foi atualizado para mostrar um método diferente, em que não podemos ter certeza de que o ano está entre parênteses. Aqui lemos o resultado da avaliação do grep como uma matriz, no caso de haver várias correspondências, e depois fazer uma verificação de sanidade no ano - ou seja, o ano deve ser entre 1970 e 2020; caso contrário, assumimos que não é um ano.

Observe que o comando readarray (também conhecido como mapfile) está apenas nas versões Bash 4.x + . Na parte inferior é uma versão mais portátil usando apenas read . Pode ser complicado analisar a saída de find sem quebras devido a espaços ou caracteres especiais nos nomes dos arquivos. / p>

Script 1

#!/bin/bash
# Create test files
touch abcd\({2001,1985,1984,1931}\)efgh.m2ts
touch abcd{24001,198a5,19b84,1912331,1293}.m2ts
touch "abcd 1232 adffd.m2ts"
touch "Liam sur la moto (VHS) (2001) - Maison 13100.m2ts"
touch "M&L Plage 1080i (2012) - Camargue 30240.m2ts" 
TestScriptResultFile="./CamCorderFindResult.file"
touch $TestScriptResultFile

regexPat='\(\K[0-9]{4,4}(?=\))'

readarray fileList <<<"$(IFS="\n" ; find . -name "*.m2ts" -exec basename {} \;)"
for i in "${fileList[@]}"; do 
  echo "Processing File: $i"
  if year=$(grep -oP "$regexPat" <<<"$i");    then
    if [ "$year" -le 1984 ]; then
      echo "1984 or earlier: $i" >> "$TestScriptResultFile"
    else
      echo "After 1984: $i" >> "$TestScriptResultFile"
    fi
  else
    echo "No valid year found in file $i"
  fi
done

1. Usando o comando find para obter uma lista de arquivos e armazená-la em uma matriz usando readarray .

  • Defina o separador de campo para uma nova linha: IFS=$'\n'
  • Use um argumento -exec em find , que executará basename em cada arquivo para obter apenas o nome do arquivo e não o caminho.
  • A saída find é direcionada para uma matriz usando substituição de comando e um < Aqui String ', <<< e o comando readarray

2. Loop na matriz de nomes de arquivos

3. Use grep e regexPat para encontrar o ano incorporado

  • O padrão regex que usei corresponderá a 6 caracteres em uma string quando o primeiro caractere for ( , seguido por exatamente 4 números [0-9]{4,4} e fechado por ) no final.

  • Para produzir somente os 4 números entre (esperançosamente o ano), o argumento -P é dado ao grep para 'Perl Regex' que permite separar caracteres combinados de caracteres capturados (saída), entre outros coisas.

  • O /K fará com que o grep não exiba nada que corresponda antes do /K no padrão (também conhecido como olhe para frente ).
  • Por fim, o ) de fechamento é removido da saída usando uma não captura semelhante a look-behind semelhante à /K . Você pode usar basicamente a mesma sintaxe para ambos, o script inferior mostra o método de look-ahead que não usa /K .

  • o -o sinalizador informa ao grep para exibir somente a parte correspondente da string capturada, que no nosso caso será um número de 4 dígitos.

O restante do script verifica o número em relação a 1984 e o registra de acordo.

Aqui está outra abordagem mais compacta.

2 coisas para notar aqui

  • find recebe o argumento -print0 que terminará com o valor nulo saída.
  • O comando read recebe o argumento -d '' , que informa sua entrada como terminada em null. Uma string nula geralmente é escrita em '' em texto simples; no Bash você pode usar $'%code%' ou %code%

Script 2

#!/bin/bash

TestScriptResultFile="./CamCorderFindResult.file"
touch $TestScriptResultFile

regexPat='(?<=[^0-9])[0-9]{4,4}(?=[^0-9])'
find . -name "*.m2ts" -print0 | while IFS= read -r -d '' k; do
  i="$(basename "$k")"
   echo "Processing File: $i"
     if year=($(grep -oP "$regexPat" <<<"$i")); then
     for yr in "${year[@]}"; do
       if [ "$yr" -lt 1970 ] || [ "$yr" -gt 2020 ]; then
         echo "   x Out of range year ($yr) parsed from $i"
       else
         echo "   o Found year $yr"
         if [ "$yr" -le 1984 ]; then
           echo "1984 or earlier: $i" >> "$TestScriptResultFile"
         else
           echo "After 1984: $i" >> "$TestScriptResultFile"
         fi
      fi
     done
   else
     echo "   x No valid year found in file $i"
  fi
done
    
por 13.09.2016 / 19:54