Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Deleting all files except ones mentioned in config file

Tags:

linux

bash

shell

Situation:

I need a bash script that deletes all files in the current folder, except all the files mentioned in a file called ".rmignore". This file may contain addresses relative to the current folder, that might also contain asterisks(*). For example:

1.php
2/1.php
1/*.php

What I've tried:

  • I tried to use GLOBIGNORE but that didn't work well.
  • I also tried to use find with grep, like follows:

    find . | grep -Fxv $(echo $(cat .rmignore) | tr ' ' "\n")

like image 432
Stanislav Goldenshluger Avatar asked Oct 17 '22 15:10

Stanislav Goldenshluger


1 Answers

It is considered bad practice to pipe the exit of find to another command. You can use -exec, -execdir followed by the command and '{}' as a placeholder for the file, and ';' to indicate the end of your command. You can also use '+' to pipe commands together IIRC.

In your case, you want to list all the contend of a directory, and remove files one by one.

#!/usr/bin/env bash

set -o nounset
set -o errexit
shopt -s nullglob # allows glob to expand to nothing if no match
shopt -s globstar # process recursively current directory

my:rm_all() {
    local ignore_file=".rmignore"
    local ignore_array=()
    while read -r glob; # Generate files list
    do
        ignore_array+=(${glob});
    done < "${ignore_file}"
    echo "${ignore_array[@]}"

    for file in **; # iterate over all the content of the current directory
    do
        if [ -f "${file}" ]; # file exist and is file
        then
            local do_rmfile=true;
            # Remove only if matches regex
            for ignore in "${ignore_array[@]}"; # Iterate over files to keep
            do
                [[ "${file}" == "${ignore}" ]] && do_rmfile=false; #rm ${file};
            done

            ${do_rmfile} && echo "Removing ${file}"
        fi
    done
}

my:rm_all;
like image 128
jraynal Avatar answered Oct 20 '22 10:10

jraynal