Delete files except those whose name matches a string
You may use this find
:
find . -type f -not \( -name '*equipe*' -o -name '*match*' -o -name '*express*' \) -delete
Exclude list of files from find
I don't think find
has an option like this, you could build a command using printf
and your exclude list:
find /dir -name "*.gz" $(printf "! -name %s " $(cat skip_files))
Which is the same as doing:
find /dir -name "*.gz" ! -name first_skip ! -name second_skip .... etc
Alternatively you can pipe from find
into grep
:
find /dir -name "*.gz" | grep -vFf skip_files
How to find all files except those with particular substring in owner name of file
I don't think you can do it directly with find
, because -user
does a straight up equality comparison, not wildcard or regular expression matching.
A quick perl
script that does the job (Pass directory names to search on the command line):
#!/usr/bin/env perl
use strict;
use warnings;
use File::Find;
use File::stat;
use User::pwent;
use feature qw/say/;
my %uids; # Cache user information
sub wanted {
my $st = stat($File::Find::name) or
(warn "Couldn't stat $File::Find::name: $!\n" && return);
return unless -f $st; # Only look at regular files
my $user =
exists $uids{$st->uid} ? $uids{$st->uid} : $uids{$st->uid} = getpwuid($st->uid);
# Print filenames owed by uids that don't include developer
# or admin in a username
say $File::Find::name if !defined $user || $user->name !~ /developer|admin/;
# Or defined $user && $user->name =~ /^\d+/ for filtering to usernames that are all digits
# Or just !defined $user for files owned by uids that don't have /etc/passwd entries
}
find(\&wanted, @ARGV);
Avoiding perl
, hmm...
find pathname -type f -printf "%u\037%p\036" | awk -F"\037" -v RS="\036" '$1 !~ /developer|admin/ { print $2 }'
will find files except ones owned by the developer and admin accounts, but for the second part, you can't tell a user id that doesn't have a name apart from a name that's all digits with this approach.
Delete all files in a folder except those with names containing
Your syntax is wrong. Here is a possible solution (you will need delayed expansion):
for %A IN (*) do @set file=%A && if !file!==!file:ntdll=! (@del /F /A !file!)
Enable delayed expansion in cmd with cmd /v:on
. You are forced to use it as you are inside a code block.
This simple command searches for all files in the current working directory, assign each in a variable and checks if they have the string ntdll
inside them. If not, they delete them.
For better understanding commands mentioned above, open a new cmd and type:
for /?
set /?
del /?
Some interesting references for further reading
- Batch file: Find if substring is in string (not in a file)
Find all files in a directory with extension .txt in Python
You can use glob
:
import glob, os
os.chdir("/mydir")
for file in glob.glob("*.txt"):
print(file)
or simply os.listdir
:
import os
for file in os.listdir("/mydir"):
if file.endswith(".txt"):
print(os.path.join("/mydir", file))
or if you want to traverse directory, use os.walk
:
import os
for root, dirs, files in os.walk("/mydir"):
for file in files:
if file.endswith(".txt"):
print(os.path.join(root, file))
Windows command to delete all files except the specified list of files which may contain spaces in their names
You have two options with the FINDSTR
command to accomplish this.
The first is to list each file individually with the /C
option.
for /f "delims=" %F in ('dir /b /a-d ^| findstr /V /I /L /E /C:"file1" /C:"file2" /C:"file3"') do del "%F"
The other option is put all your search strings in a file, one on each line and use the /G option.
for /f "delims=" %F in ('dir /b /a-d ^| findstr /V /I /L /E /G:"search.txt"') do del "%F"
find: Exclude files with the same name based on their depth in a directory
find . -type f -not -regex '\./[^/]+/file\.ext'
It will discard anything that match the regex. Here a direct subdirectory containing the file file.ext
.
The regex is run to the whole path.
\.
means starts with a.
[^/]+
means a bunch of characters not containing a/
file\.ext
meansfile.ext
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. ./
.
Related Topics
Unix - Combine All Rows into a Comma-Separated Single Row
Checking If a Binary Compiled with "-Static"
How to Untar All .Tar.Gz with Shell-Script
Checking Shared Libraries for Non Default Loaders
Are Mlock()-Ed Pages Static, or Can They Be Moved in Physical Ram
Move Lines Matching a Pattern from One File to Another
Bash - How to Print Multi Line Strings (With '\N') Using Printf
How to Trace a System Call in Linux
Sigterm Does Not Reach Node Script When Docker Runs It with '/Bin/Sh -C'
Difference Between "Machine Hardware" and "Hardware Platform"
Set Docker Image Username at Container Creation Time
Using Output of Previous Commands in Bash
How to Programmatically Invert Screen Colors in Linux
Fork() and Stdout/Stderr to The Console from Child Processes
Substituting a String in Place of Variable in Shell
Tar Error: Unexpected Eof in Archive
How to Simulate Two Consecutive Enter Key Presses for a Command in a Bash Script