Перемещение папок, если они или их подпапки содержат определенные c файлы (bash) - PullRequest
0 голосов
/ 08 мая 2020

Я новичок в bash сценариях и stackoverflow (первый вопрос). Я пытаюсь сделать довольно простую вещь, но почему-то не получаю то, что хочу (пытался использовать некоторые решения из разных потоков, но безуспешно). Возможно, вы поможете мне с простым решением.

Моя задача: искать в разных папках (в какой-нибудь основной папке) файл с именем log.txt. Если он найден, переместите соответствующую папку в другое место (это резервная папка ... log.txt указывает, что этой папке требуется резервная копия). В приведенном ниже макете я хочу создать mv folder3 вместе со всем его содержимым.

-Main
--folder1   
  ---subfolder
--folder2
  ---Subfolder2
--folder3   
   --Subfolder3
        --log.txt

#!/bin/bash
MAIN=$(find /home/rwo/Desktop/FROM/* -maxdepth 0 -type d)
for FOLDER in $MAIN; do
        if 
            find $FOLDER -maxdepth 0 -type f -name "log.txt" 
                then
                    mv $FOLDER /home/rwo/Desktop/TO

        fi
done

В приведенном выше случае папка получателя (TO) в конечном итоге получает Subfolder1, Subfolder2 и Subfolder3 (вместе с log.txt ). Что я делаю не так?

Заранее спасибо

1 Ответ

1 голос
/ 08 мая 2020

С find и bash

#!/usr/bin/env bash

while IFS= read -r file; do
  file=${file%/*}
  echo mv -v "${file%/*}" /home/rwo/Desktop/TO
done < <(find main -type f -name 'log.txt')

echo нужен, чтобы показать вам, что произойдет, удалите его, если вы считаете, что результат в порядке.


Простая симуляция

mkdir -p Main/folder{1..3}
mkdir -p Main/folder1/subfolder
mkdir -p Main/folder2/subfolder2
mkdir -p Main/folder3/subfolder3
touch Main/folder3/subfolder3/log.txt

Создайте целевой каталог

mkdir -p home/rwo/Desktop/TO

проверьте, что находится внутри основного каталога.

tree Main

Вывод

Main
├── folder1
│   └── subfolder
├── folder2
│   └── subfolder2
└── folder3
    └── subfolder3
        └── log.txt

6 directories, 1 file

Теперь скрипт соответствует Main

#!/usr/bin/env bash

while IFS= read -r file; do
  file=${file%/*}
  echo mv -v "${file%/*}" home/rwo/Desktop/TO
done < <(find Main -type f -name 'log.txt')

output

mv -v Main/folder3/ home/rwo/Desktop/TO

Удаление echo приведет к выводу

renamed 'Main/folder3/' -> 'home/rwo/Desktop/TO/folder3'

The "${file%/*}" - это форма Parameter Expansion Что в основном удаляет последний /

Так, например, вывод find main -type f -name 'log.txt'

main/folder3/subfolder3/log.txt

Удаление последнего / с расширением параметра останется только имя пути

main/folder3/subfolder3/

Применить другое расширение параметра для удаления последнего / приведет к

main/folder3/

Затем отправьте его на mv как аргумент внутри while read l oop.

<() называется Подстановка процесса

IFS= отключает функция по умолчанию встроенной read, которая удаляет конечные и начальные пробелы.

Посмотрите как читать файл или поток в bash, чтобы понять while read l oop, что опубликовано.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...