Я пытаюсь переместить файл на основе шаблона через Bash Script.

Я использую find, чтобы выбрать все файлы моей видеокамеры и сохранить результат в файл TXT.

Каждый из файлов моей видеокамеры содержит местоположение года, я хотел бы использовать Grep или что-то подобное, чтобы найти эту строку (год из 4 цифр, т.е. 1984) и сравнить эту строку, чтобы переместить файл в другую папку, если файл после 1984 года, тогда мой файл должен перейдите в папку "Marie", если файл до или, например, до 1984 года, он должен перейти в папку "Marie_Liam".

Я пробовал несколько вещей, с Grep и при чтении строки -r, но когда я сравнивал найденную строку (год), мой скрипт возвращался каждый раз после 1984 года ...

Вот мои разные попытки:

Я попробовал несколько вещей, как это (это много, а не один скрипт):

Базовый скрипт:

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

Попробуйте 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

- Еще одна попытка -

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

- Еще одна попытка -

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

Спасибо за вашу помощь.

С наилучшими пожеланиями.

1 ответ1

0

Я обновил сценарии на основе примеров имен файлов, которые вы предоставили в своем комментарии:

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

Я придумал два метода для обработки этого соглашения об именах.

Первый заключается в предположении, что в каждом случае год заключен в круглые скобки. Я обновил «первый» скрипт, чтобы отразить этот случай; это просто обновление шаблона регулярных выражений, которое используется.

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

Второй скрипт был обновлен, чтобы показать другой метод, где мы не можем быть уверены, что год заключен в круглые скобки. Здесь мы зачитываем результат оценки grep в виде массива в случае множественных совпадений, а затем выполняем проверку работоспособности года - т.е. год должен быть между 1970 и 2020 годами; в противном случае мы предполагаем, что это не год.


Обратите внимание, что команда readarray (она же mapfile) есть только в версиях Bash 4.x+. Внизу - более портативная версия с использованием только что read . Может быть сложно проанализировать вывод команды find без проблем из-за пробелов или специальных символов в именах файлов.

Сценарий 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. Использование команды find для получения списка файлов и сохранения его в массиве с использованием readarray .

  • Установите разделитель полей на новую строку: IFS=$'\n'
  • Используйте аргумент -exec в find который будет запускать basename для каждого файла, чтобы получить только имя файла, а не путь.
  • Выходные данные find направляются в массив с помощью подстановки команд и команд ' Here String', <<< и команда readarray

2. Цикл в массиве имен файлов

3. Используйте grep и regexPat, чтобы найти внедренный год

  • Шаблон регулярного выражения, который я использовал, будет соответствовать 6 символам в строке, когда первый символ представляет собой ( последующим ровно 4 числами [0-9]{4,4} и закрытый символом a ) в конце.

  • Чтобы вывести только 4 числа между (надеюсь, год), аргумент -P задается grep для 'Perl Regex', который позволяет отделить совпадающие символы от захваченных (выходных) символов, среди прочего.

  • /K заставит grep не выводить ничего, что совпадает с /K в шаблоне (так называемый прогноз).
  • Наконец, закрывающее значение ) удаляется из выходных данных с помощью скрытого отсутствия захвата, подобного /K Вы можете использовать в основном один и тот же синтаксис для обоих, нижний скрипт показывает метод упреждения, который не использует /K

  • флаг -o указывает grep выводить только захваченную, совпадающую часть строки, которая в нашем случае будет четырехзначным числом.

Остальная часть скрипта проверяет число по отношению к 1984 и записывает его соответствующим образом.


Вот еще один более компактный подход.

2 вещи, чтобы отметить здесь

  • find получает аргумент -print0 который завершает вывод.
  • Команде read присваивается аргумент -d '' , который сообщает, что ее ввод завершается нулем. Нулевая строка обычно пишется \0 в виде простого текста; в Bash вы можете использовать '' или $'\0'

Сценарий 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

Всё ещё ищете ответ? Посмотрите другие вопросы с метками .