Bash - Ignore Hidden Files and Empty Source Directory When Copying

cp -r without hidden files

You can use rsync instead of cp:

rsync -av --exclude=".*" src dest

This excludes hidden files and directories. If you only want to exclude hidden directories, add a slash to the pattern:

rsync -av --exclude=".*/" src dest

Check if directory contains only hidden files and no directories

Generally don't use ls in scripts.

Assuming you have the default values for nullglob etc,

files=(./*)
if [[ "${files[@]}" = './*' ]]; then
echo "Specified directory is empty" >&2
exit 1
fi
dirs=(./*/)
if [[ "${#dirs[@]}" = "${#files[@]}" ]]; then
echo "Specified directory contains only subdirectories and no files" >&2
exit 1
fi
hidden=(./.*)
if [[ "${#hidden[@]}" = "${#files[@]}" ]]; then
echo "Specified directory contains only hidden files" >&2
exit 1
fi

There is an obvious race condition here, in that another process could add a new hidden file after files gets assigned, but before hidden gets assigned, for example.

The use of arrays makes this Bash-only; this should be obvious, but many beginners are confused about the difference between sh and bash.

The immediate error in your attempt is that '"$dir"/.*' is in single quotes, and so gets interpreted verbatim (and even if you fixed the quoting, . in a regex matches any character, not a literal dot). But more broadly, it seems excessive to use find when the shell itself can tell you what files you have.

Having trouble writing a Bash script that checks if a directory is empty and deletes it if it is

rmdir will not delete a directory that's not empty, so you can do the check and removal in one go with

while rmdir "$PFAD" 2>/dev/null; do
echo "$PFAD ist leer und wird gelöscht"
PFAD="$(dirname "$PFAD")"
done

The 2> /dev/null is there to suppress the error message you get if a directory is not empty and rmdir refuses to delete it because of that.

Note that the dollar sign at the beginning of

$PFAD=`echo $PFAD | rev | cut -d/ -f2- | rev`

is a problem in that it assigns the output of the command to a variable named after the contents of $PFAD. It could be solved by removing the dollar sign, but dirname is meant to deal with directories and better suited to the task. You should probably take care to test for . though, in case you use relative paths and the current working directory ends up empty, and possibly /. Although, if / ends up empty, the script will run into trouble before the infinite dirname loop becomes a problem.

How to ignore all hidden directories/files recursively in a git repository?

Just add a pattern to .gitignore

.*
!/.gitignore

Edit: Added the .gitignore file itself (matters if it is not yet commited).

How do you delete all hidden and non-hidden files except one?

This will delete everything in the current directory that you have permission to remove, recursively, preserving the file named by -path, and its parent path.

# remove all files bar one
find . -mindepth 1 -not -type d -not -path ./file/to/keep -exec rm -rf {} +

# then remove all empty directories
find . -mindepth 1 -type d -exec rmdir -p {} + 2>/dev/null

rmdir will get fed a lot of directories it's already removed (causing error messages). rmdir -p is POSIX. This would not work without -p.

You can keep more files with additional -path arguments, and/or glob patterns. The paths must match the starting point, i.e. ./.

How to ignore `.*` folders and files when using `find` command?

I believe there are several ways to do this, for example:

find . \( ! -regex '.*/\..*' \) -type f -name "something"

The first example won't show you any hidden file or directory.

find . \( ! -regex '.*/\..*/..*' \) -type f -name "something"

The second just discards the hidden directories, showing the hidden files into normal directories.

It's the regular expression option of find.

Here is a complete explanation: find command search only non hidden directories

EDIT 1:

find . -type f -not -name ".*"

Ignore empty matches while glob expanding on bash for loop

You want the nullglob option; patterns that don't match anything are ignored, rather than treated literally.

shopt -s nullglob
for f in *.does_not_exist; do
echo "This won't be reached"
done

Ignoring directories in Git repositories on Windows

Create a file named .gitignore in your project's directory. Ignore directories by entering the directory name into the file (with a slash appended):

dir_to_ignore/

More information is here.

How do I add an empty directory to a Git repository?

Another way to make a directory stay (almost) empty (in the repository) is to create a .gitignore file inside that directory that contains these four lines:

# Ignore everything in this directory
*
# Except this file
!.gitignore

Then you don't have to get the order right the way that you have to do in m104's solution.

This also gives the benefit that files in that directory won't show up as "untracked" when you do a git status.

Making @GreenAsJade's comment persistent:

I think it's worth noting that this solution does precisely what the question asked for, but is not perhaps what many people looking at this question will have been looking for. This solution guarantees that the directory remains empty. It says "I truly never want files checked in here". As opposed to "I don't have any files to check in here, yet, but I need the directory here, files may be coming later".



Related Topics



Leave a reply



Submit