This is what look like my directory structure :
pi
|___
|
folder1
|____otherfolder1
folder2
|____otherfolder2
folder3
|____otherfolder3
I used this command :
find /home/pi -name "*folder*" -type d
But I only want folder1,2,3 but not subfolders (ohterfolder1,2,3)
I found using -maxdepth 1
find /home/pi -maxdepth 1 -name "*folder*" -type d
Related
I have hundreds of subdirectories and I have to find out every subdirectory that has files with a specific system permission (in this case 0755).
I'm trying to achieve that with:
find . -maxdepth 2 -type f -perm 0775 -printf '%h\n' | wc -l
This command shows multiple times the same directory name, I would need to display only one occurrence for each directory.
Thanks for any help!
find . -maxdepth 2 -type f -perm 0775 -printf '%h\n' | sort | uniq | wc -l
You search about files with type f and print only the directories of this files with %h. That is not what you need. Search about directories with -type d and delete the printf option complete.
find . -maxdepth 2 -type d -perm 0775 | wc -l
Say I want to find all directories that contain a certain string (say a here) that also contain files that contain a certain other string (say that are .txt files). What are the different ways of doing this? One way is to do a command substitution, such as:
mkdir dira; mkdir dirb
touch dira/file1.txt; touch dira/file2.doc; touch dirb/file3.doc
find `find . -type d -iname '*a'` -type f -iname '*.doc'
However, this does not work if I am trying to find hidden directories that contain this file:
find `find . -type d -iname '.*'` -type f -iname '*.doc'
In this case, it just prints to stdout the inside find. How does one do this? The more ways to do this, the more instructive. A shell script would also be instructive.
This works for me:
#!/bin/bash
# Setup test directories
mkdir dira dirb .dirc .dird .hiddena
# Setup test files
touch dira/filea1.doc dira/filea2.doc dira/filea3.txt
touch dirb/fileb1.doc dirb/fileb2.doc dirb/fileb3.txt
touch .dirc/filec1.doc .dirc/filec2.doc .dirc/filec3.txt
touch .dird/filed1.doc .dird/filed2.doc .dird/filed3.txt
touch .hiddena/filehiddena1.doc .hiddena/filehiddena2.doc .hiddena/filehiddena3.txt
find . -type d -name "*a" -print | while read DIR
do
find $DIR -type f -name "*a*.doc" -print
done
Output:
$ ./t.bash
./dira/filea1.doc
./dira/filea2.doc
./.hiddena/filehiddena2.doc
./.hiddena/filehiddena1.doc
My first version used a for loop but that can cause issues if you have spaces in your directory names, thus the while read loop.
From your comment, I did this:
# Setup test directories
mkdir dira dirb .dirc .dird .hiddena
# Setup test files
touch dira/filea1.doc dira/filea2.doc dira/filea3.txt
touch dirb/fileb1.doc dirb/fileb2.doc dirb/fileb3.txt
touch .dirc/filec1.doc .dirc/filec2.doc .dirc/filec3.txt
touch .dird/filed1.doc .dird/filed2.doc .dird/filed3.txt
touch .hiddena/filehiddena1.doc .hiddena/filehiddena2.doc .hiddena/filehiddena3.txt
touch .hiddena/z
find . -type d -name "*a" -print | while read DIR
do
#find $DIR -type f -name "*a*.doc" -print
find $DIR -type f -name z -print
done
The output I get is:
$ ./t.bash
./.hiddena/z
So I do not understand why you get double z.
To prevent the actual directory being evaluated (as ./ or ../pwd/), just use:
find .* -mindepth 1 -maxdepth 1 -type f -iname '*.doc'
.dira/file11.doc
.dira/file10.doc
.dira/file9.doc
.dirb/file11.doc
.dirb/file10.doc
.dirb/file9.doc
After using
touch .dir{a..b}/file{9..11}.doc
with the longer pattern .dir* it is more easy:
find .dir* -type f -iname '*.doc'
.dira/file11.doc
.dira/file10.doc
.dira/file9.doc
.dirb/file11.doc
.dirb/file10.doc
.dirb/file9.doc
Command substitution works too (don't use the outdated backticks, please)
find $(find . -mindepth 1 -type d -iname ".*") -type f -iname '*.doc'
./.dirb/file11.doc
./.dirb/file10.doc
./.dirb/file9.doc
./.dira/file11.doc
./.dira/file10.doc
./.dira/file9.doc
I have a directory with this structure:
main/
Antispam/res/values/
strings.xml
plurarls.xml
arrays.xml
Backup/res/values/
strings.xml
plurarls.xml
arrays.xml
etc.
Antispam and Backup have other folders inside, but I do not need those. I just want to have only the values folder with the three XML files (strings.xml, plurarls.xml and arrays.xml). How can I do that?
if you run this in the parent directory:
find . -regex '.*backup.*'
you would have something like this:
./backup
./backup/res
./backup/res/value
./backup/res/value/00.xml
./backup/res/value/02.xml
./backup/res/value/01.xml
And then you can invert the match by -not
find . -not -regex '.*backup.*'
and of course you can make it more specific with -type d and literal ./
find . -type d -not -regex './backup.*'
and then do any thing you like with the output
This is what I would do. Basically just find folders excluding the parent folders and send them to oblivion.
find main/Antispam/res/values/ '!' -path main/Antispam/res/values/ -type d | xargs rm -f -r $1
find main/Backup/res/values '!' -path main/Backup/res/values -type d | xargs rm -f -r $1
Hope it works for you! :)
This work for me:
ale8530#vmi81507:~/Scrivania/APK-Tools-Linux-master/working$ find . -regex '.*res/values/strings.*'
./WaliLive/res/values/strings.xml ./SystemAdSolution/res/values/strings.xml ./SampleExtAuthService/res/values/strings.xml ./DocumentsUI/res/values/strings.xml ./CaptivePortalLogin/res/values/strings.xml ./SoundRecorder/res/values/strings.xml ./ExternalStorageProvider/res/values/strings.xml ./MiuiCompass/res/values/strings.xml ./CloudBackup/res/values/strings.xml ./BackupRestoreConfirmation/res/values/strings.xml ./AntHalService/res/values/strings.xml ./MiuiSuperMarket/res/values/strings.xml ./DownloadProvider/res/values/strings.xml ./VpnDialogs/res/values/strings.xml ./XiaomiAccount/res/values/strings.xml ./SpacesCore/res/values/strings.xml ./CdmaCallOptions/res/values/strings.xml
Can you copy this output to another director
y? Keeping the same output?
For example
From-->./WaliLive/res/values/strings.xml to ./WaliLive.apk/res/values/strings.xml
Thanks
PLEASE BACKUP YOU DATA BEFORE YOU TRY!!!
if you don't care about empty dirs (or you don't care to do everything with one command), i'll do something like:
find ! -name strings.xml ! -name plurarls.xml ! -name arrays.xml -type f -delete
if you care about empty dirs:
find -type d -print0 | xargs -0 rmdir -p
Consider the following folder structure
root/dirA/the_folder
root/dirA/dir2/the_folder
root/dirB/the_folder
root/dirB/dir2/the_folder
I want to recursively find and tar the dirA/the_folder and dirB/the_folder. However when I use
find root/ -name 'the_folder' -type d | xargs tar cvf myTar.tar
It will pack all folders (containing dir2/the_folder) and I don't want that. What is the solution?
In your case, wouldn't just this be enough?
tar cfv mytar.tar root/*/the_folder/
Use the -maxdepth option of find to limit the recursion depth:
find root/ -maxdepth 2 -name 'the_folder' -type d
Try man find for lots of useful options that find offers. You will be surprised. For example, you can do away with the | xargs by using find's -exec option:
find root/ -maxdepth 2 -name 'the_folder' -type d -exec tar cvf myTar.tar {} +
Here is the structure of my dir:
./archive
/sub1
- file1
- file2
/sub2
- file3
- file4
I try with this command to find all the files that older than 6 months to delete it:
find ./archive -mindepth 1 -mtime +180 -delete
All the files and sub directory is deleted, what I want just the file1, file2, file3, file4 that delete, not include the sub1 and sub2, please advise.
find supports the -type option. Use that to specify regular file with f as the argument.
find ./archive -mindepth 1 -mtime +180 -delete -type f
include a -type f flag that restricts the find to only files:
find ./archive -mindepth 1 -mtime +180 -delete -type f
Add -type f option to exclude directories:
find ./archive -mindepth 1 -mtime +180 -type f -delete