I have a music volume on my NAS which contains plenty of CD's.The file names are typically 01.name.mp3 , 02.name.mp3 etc. On another part of the NAS I store snapshots taken and named at each hour of the day 00-00-00.jpg , 01-00-00.jpg.... 23-00-00.jpg I made a crontab to delete the snapshots before 7am as they were usually dark , so no point in keeping them.
Well guess what , I had a link in snapshots folder which I had forgotten ,pointing to the music files. So after a while I realized most of my music files from 01-name.mp3 to 07-name.jpg had been deleted. What I am trying to do is assess the damage & display only the directories that contain files starting with 09-name.mpg AND do not contain 01-name.mp3.This folder (or cd) has had the files lower than 07 deleted.
Ideally during the search I would like to eliminate any other directory containing a non-numeric name like "main-theme.mp3" as I know these folders are complete.
I did try:
find . -name "09*" -a ! -name "01*"but it didn't work. I also tried this which did not work
find . -mindepth 2 -maxdepth 2 -type d '!' -exec test -e "{}/01*" ';' -printMy system:
Linux fut-NUC7i3BNH 4.15.0-96-generic #97-Ubuntu SMP Wed Apr 1 03:25:46 UTC 2020 x86_64 x86_64 x86_64 GNU/Linux
NAME="Ubuntu"
VERSION="18.04.4 LTS (Bionic Beaver)"
ID=ubuntu
ID_LIKE=debian
PRETTY_NAME="Ubuntu 18.04.4 LTS"
VERSION_ID="18.04"
HOME_URL=""
SUPPORT_URL=""
BUG_REPORT_URL=""
PRIVACY_POLICY_URL=""
VERSION_CODENAME=bionic
UBUNTU_CODENAME=bionic 1 2 Answers
The next command
- looks for all unique folders containing files starting with
09* - looks for all unique folders containing files starting with
01* - removes lines which point to
01*files from output which points to09*files.
Number of 09* files should be bigger then number of 01* files because a part of them have been removed, so the command will output only folders with 01* files removed.
snpath=$(echo ~/test/snapshots/) && \
find $snpath -name "09*" | sed 's|\(.*\)/.*|\1|' | sort | uniq > allf.txt && \
find $snpath -name "01*" | sed 's|\(.*\)/.*|\1|' | sort | uniq > notallf.txt && \
grep -Fvxf notallf.txt allf.txt | grep -oP "^$snpath\K.*"$ snpath=$(echo ~/test/snapshots/)- full path tosnapshotsfolderfind $snpath -name "09*"finds all files starting with 09 with their full pathssed 's|\(.*\)/.*|\1|'strips files names leaving parent directories paths onlysort | uniqremoves duplicate paths lines leaving only unique directories namesfind $snpath -name "01*" | sed 's|\(.*\)/.*|\1|finds undesired directories we do not want to see (they do not contain removed files)grep -Fvxf notallf.txt allf.txtremoves undesired folders names from all folders' list leaving only folders that contain09*files names and do not contain01*files namesawk 'NR==FNR{a[$0];next} !($0 in a)' notallf.txt allf.txtcould be used instead of previousgrepcommandgrep -oP "^$snpath\K.*"path to snapshots folder from output$ tree ./ ./ ├── allf.txt ├── Alligator Records 20th Anniversary Collection │ ├── CD1 │ │ ├── 01 - Hound Dog Taylor And The Houserockers .mp3 │ │ ├── 02 - James Cotton - No Cuttin Loose.mp3 │ │ ├── 03 - Black Cat Bone .mp3 │ │ ├── 04 - Professor Longhair - Big Chief.mp3 │ │ ├── 05 - Koko Taylor - Thats Why Im Crying.mp3 │ │ ├── 06 - Tinsley Ellis - Double-eyed Whammy.mp3 │ │ ├── 07 - Lucky Peterson - Im Free.mp3 │ │ ├── 08 - A.C. Reed-Stevie Ray Vaughan mp3 │ │ ├── 09 - Little Charlie And The Nightcats - Rain.mp3 │ │ └── file1 │ ├── CD2 │ │ ├── 09 - Bessie Smith,Moan, You Moaners.mp3 │ │ ├── 10 - Louis Armstrong,Nobody Knows The Trouble Ive Seen.mp3 │ │ ├── 11 - Golden Gate Quartet,The Valley Of Time.mp3 │ │ └── 12 - Golden Gate Quartet,The Sun Didnt Shine.mp3 │ └── file2 ├── file └── notallf.txt 3 directories, 18 files
Result:
$ snpath=$(echo ~/test/snapshots/) && find $snpath -name "09*" | sed 's|\(.*\)/.*|\1|' | sort | uniq > allf.txt && find $snpath -name "01*" | sed 's|\(.*\)/.*|\1|' | sort | uniq > notallf.txt && grep -Fvxf notallf.txt allf.txt | grep -oP "^$snpath\K.*"
Alligator Records 20th Anniversary Collection/CD2 9 You can do it in two steps: find directories which contain name number one, then find in the output directories which contain name number 2.
Example:
find . -name "09* > output_first_search
cat output_first_search | grep "01*" 2