Moving photos and renaming them if they exist? - linux

I'm trying to move photos from directories to one directory with find. It works good:
find /origin/path \( -iname '*.jpg' -o -iname '*.jpeg' -o -iname '*.JPG' -o -iname '*.JPEG' -o -iname '*.PNG' -o -iname '*.png' -o -iname '*.gif' -o -iname '*.GIF' \) -type f -exec mv -nv -t /final/path -- {} +;
How to rename files if they have the same name (but different photos)?

You can use the --backup=t option for mv. This will append an increasing numbered suffix to files whose target already exists.
$ find /tmp/test -type f
/tmp/test/dir2/image.jpg
/tmp/test/dir3/image.jpg
/tmp/test/dir1/image.jpg
/tmp/test/dir4/image.jpg
$ mkdir /tmp/test2
$ find /tmp/test -iname '*.jpg' -print0 | xargs -0 mv -v --backup=t --target-directory=/tmp/test2
‘/tmp/test/dir2/image.jpg’ -> ‘/tmp/test2/image.jpg’
‘/tmp/test/dir3/image.jpg’ -> ‘/tmp/test2/image.jpg’ (backup: ‘/tmp/test2/image.jpg.~1~’)
‘/tmp/test/dir1/image.jpg’ -> ‘/tmp/test2/image.jpg’ (backup: ‘/tmp/test2/image.jpg.~2~’)
‘/tmp/test/dir4/image.jpg’ -> ‘/tmp/test2/image.jpg’ (backup: ‘/tmp/test2/image.jpg.~3~’)
$

sorry i didn't because i'm on windows now, but below script should do it
files_list=$(find /origin/path \( -iname '*.jpg' -o -iname '*.jpeg' -o -iname '*.JPG' -o -iname '*.JPEG' -o -iname '*.PNG' -o -iname '*.png' -o -iname '*.gif' -o -iname '*.GIF' \) -type f)
for file in ${files_list}
do
counter=0
while true
do
if [[ ! -a ${file} ]]
then
mv "${file}" "/final/path/${file}"
break
else
file="${file}${counter}"
(( counter++ ))
fi
done
done

Related

Linux Find command- exclude find based on file name

I feel like this is a ridiculously easy question but I cannot find a simple regex answer for this. Basically, I am trying to use find to get a list of all files in my system with some exclusions. One of these exclusions is any file that ends in .Foo.cs, or any file named FooInfo.cs. I have successfully excluded a couple directories from my search, but cannot seem to exclude these two files. I've tried using -name, but would -name even work for this? Below is my expression. Thanks.
find . ! -name 'FooInfo.cs' ! -name '*.Foo.cs' -type d \( -name Foo-o -name 2Foo -o -name 2_Foo \) -prune -o -type f ! -size 0 \( -name "*.java" -o -name "*.cs" -o -name "*.cpp" -o -name "*.cxx" -o -name "*.cc" -o -name "*.c" -o -name "*.h" -o -name "*.scala" -o -name "*.css" -o -name "*.html" -o -name "*.bat" -o -name "*.js" \) -exec realpath {} \;| xargs grep -L CUSTOMERINFO | sed -e 's/$/\r/g' >> ../output.txt
So I'm not sure why, but I ended up fixing this by changing the order of what I'm excluding. Instead of excluding at the very beginning, the following worked (moving the ! -name '.FOO.cs' and ! -name '.fooinfo.cs' to right after the declaration type -f).
I'm assuming this worked because they are files so they must be flagged with type -f. But please comment and correct below if you know why.
find . -type d \( -name Foo-o -name 2Foo -o -name 2_Foo \) -prune -o -type f ! -size 0 ! -name 'FooInfo.cs' ! -name '*.Foo.cs' \( -name "*.java" -o -name "*.cs" -o -name "*.cpp" -o -name "*.cxx" -o -name "*.cc" -o -name "*.c" -o -name "*.h" -o -name "*.scala" -o -name "*.css" -o -name "*.html" -o -name "*.bat" -o -name "*.js" \) -exec realpath {} \;| xargs grep -L CUSTOMERINFO | sed -e 's/$/\r/g' >> ../output.txt

cscope for files which are symlinks

I have a source directory with several files. Some of them are symlinks to other files.
I created a cscope.files file. But when I execute cscope. It complains for the files that are symlinks:
cscope: cannot find file /home/bla/source/file.cc
I think it's not very good, but maybe the correct way to go is to change the "find" script, to just write the destination of the symlink instead?
Currently I'm using:
# Write only the files which are NOT symlinks
find `pwd` \( \( -iname "*.c" -o -iname "*.cc" -o -iname "*.h" \) -and \( -not -type l \) \) -print > cscope.files
# Add the target of the symlink for all files matching the right extension, and are symlinks
find `pwd` \( \( -iname "*.c" -o -iname "*.cc" -o -iname "*.h" \) -and -type l \) -printf "%l\n" >> cscope.files
But this seems like a terrible solution. Still looking for a better one
I think you can use the command to find all real paths in a folder that you searched
find -L [your searched folder] -name [your searched pattern] -exec realpath {} \; >> cscope.files
For example, if I would like to add developed folder and linux kernel header to cscope.files, I will the these commands:
find -L `pwd` -iname "*.c" -o -iname "*.h" > cscope.files
find -L /usr/src/linux-headers-3.19.0-15-generic/ -iname '*.h' -exec realpath {} \; >> cscope.files
I hope the answer can help you.
For example if you want to give / as your path for cscope, and want cscope to search files with extensions .c/.h/.x/.s/.S you can give the find command as:
find / -type f -name "*.[chxsS]" -print -exec readlink -f {} \;> cscope.files
This will include regular files, including targets of symbolic links.
I just do the following to avoid symbolic links, as well get the absolute path in the cscope.files. With absolute path you can search from any directory in your sandbox when cscope is integrated with the vim editor
find /"path-to-your-sandbox" -path .git -prune -o -name "*.[ch]" -exec readlink -f {} \; > cscope.files
Note: if you omit -print from the find it does not put the symbolic link path in your cscope.files only the resolved path.
Better in a bash script:
#!/bin/bash
#
# find_cscope_files.sh
extension_list=(c cpp cxx cc h hpp hxx hh)
for x in "${extension_list[#]}"; do
find . -name "*.$x" -print -exec readlink -f {} \;
done
For reference for others I'm currently using.
find "$(pwd)" \( -name "*.[chCS]" -o -name "*.[ch][ci]" -o -name "*.[ch]pp" -o -name "*.[ch]++" -o -name "*.[ch]xx" ) -not \( -ipath "*unittest*" -or -ipath "*regress*" \) \( \( -type l -xtype f -exec readlink -f {} \; \) -o \( -type f -print \) \) >cscope.files
cscope -q -R -b -i cscope.files

Find with or operators

I've a bash command who should find and remove files:
/usr/bin/find /srv/www/vest2/produktion/ -type f \( -iname 'vest*.xml' -o -iname 'vest*.xls'-o -iname 'vwk*.xls' \) -ctime +90 -exec rm {} \ ';'
but it doesn't work.
Whats the problem?
Many thanks
Martin
Remove the single quotes around the final semi colon
Before:
/usr/bin/find /srv/www/vest2/produktion/ -type f \( -iname 'vest*.xml' -o -iname 'vest*.xls'-o -iname 'vwk*.xls' \) -ctime +90 -exec rm {} \ ';'
/usr/bin/find: missing argument to `-exec'
Now:
/usr/bin/find /srv/www/vest2/produktion/ -type f \( -iname 'vest*.xml' -o -iname 'vest*.xls'-o -iname 'vwk*.xls' \) -ctime +90 -exec rm {} \;
/usr/bin/find: `/srv/www/vest2/produktion/': No such file or directory
If that directory existed for me, it would have executed.

How can I make find pass file names to exec without the leading directory name?

Someone created directories with names like source.c. I am doing a find over all the directories in a tree. I do want find to search in the source.c directory, but I do not want source.c to be passed to the grep I am doing on what is found.
How can I make find not pass directory names to grep? Here is what my command line looks like:
find sources* \( -name "*.h" -o -name "*.cpp" -o -name "*.c" \) -exec grep -Hi -e "ThingToFind" {} \;
Add -a -type f to your find command. This will force find to only output files, not directories. (It will still search directories):
find sources* \( -name "*.h" -o -name "*.cpp" -o -name "*.c" \) -a -type f -exec grep -Hi -e "ThingToFind" {} \;

Maximum limit for 'find / -name 'file' -o -iname 'file2' -o -iname 'file3'..." etc

I am trying to organize a massive amount of files based on file extension.
My code is as follows (sorry for the length):
sudo find /malon/tyler/Desktop/test/all/ -iname '*.doc' -o -iname '*.docx' -o -iname '*.log' -o -iname '*.msg' -o -iname '*.odt' -o -iname '*.pages' -o -iname '*.rtf' -o -iname '*.tex' -o -iname '*.txt' -o -iname '*.wpd' -o -iname '*.wps' -o -iname '*.csv' -o -iname '*.dat' -o -iname '*.gbr' -o -iname '*.ged' -o -iname '*.ibooks' -o -iname '*.key' -o -iname '*.keychain' -o -iname '*.pps' -o -iname '*.ppt' -o -iname '*.pptx' -o -iname '*.sdf' -o -iname '*.tar' -o -iname '*.tax' -o -iname '*.vcf' -o -iname '*.xml' -o -iname '*.aif' -o -iname '*.iff' -o -iname '*.m3u' -o -iname '*.m4a' -o -iname '*.mid' -o -iname '*.midi' -o -iname '*.mp3' -o -iname '*.mpa' -o -iname '*.ra' -o -iname '*.wav' -o -iname '*.wma' -o -iname '*.3g2' -o -iname '*.3gp' -o -iname '*.asf' -o -iname '*.asx' -o -iname '*.avi' -o -iname '*.flv' -o -iname '*.m4v' -o -iname '*.mov' -o -iname '*.mp4' -o -iname '*.mpg' -o -iname '*.mpeg' -o -iname '*.rm' -o -iname '*.srt' -o -iname '*.swf' -o -iname '*.vob' -o -iname '*.wmv' -o -iname '*.3dm' -o -iname '*.3ds' -o -iname '*.max' -o -iname '*.obj' -o -iname '*.bmp' -o -iname '*.dds' -o -iname '*.gif' -o -iname '*.jpg' -o -iname '*.jpeg' -o -iname '*.png' -o -iname '*.psd' -o -iname '*.pspimage' -o -iname '*.tga' -o -iname '*.thm' -o -iname '*.tif' -o -iname '*.tiff' -o -iname '*.yuv' -o -iname '*.ai' -o -iname '*.eps' -o -iname '*.ps' -o -iname '*.svg' -o -iname '*.indd' -o -iname '*.pct' -o -iname '*.pdf' -o -iname '*.xlr' -o -iname '*.xls' -o -iname '*.xlsx' -o -iname '*.accdb' -o -iname '*.db' -o -iname '*.dbf' -o -iname '*.mdb' -o -iname '*.pdb' -o -iname '*.sql' -o -iname '*.apk' -o -iname '*.app' -o -iname '*.bat' -o -iname '*.cgi' -o -iname '*.com' -o -iname '*.exe' -o -iname '*.gadget' -o -iname '*.jar' -o -iname '*.pif' -o -iname '*.vb' -o -iname '*.wsf' -o -iname '*.dem' -o -iname '*.gam' -o -iname '*.nes' -o -iname '*.rom' -o -iname '*.sav' -o -iname '*.dwg' -o -iname '*.dxf' -o -iname '*.gpx' -o -iname '*.kml' -o -iname '*.kmz' -o -iname '*.asp' -o -iname '*.aspx' -o -iname '*.cer' -o -iname '*.cfm' -o -iname '*.csr' -o -iname '*.css' -o -iname '*.htm' -o -iname '*.html' -o -iname '*.js' -o -iname '*.jsp' -o -iname '*.php' -o -iname '*.rss' -o -iname '*.xhtml' -o -iname '*.crx' -o -iname '*.plugin' -o -iname '*.fnt' -o -iname '*.fon' -o -iname '*.otf' -o -iname '*.ttf' -o -iname '*.cab' -o -iname '*.cpl' -o -iname '*.cur' -o -iname '*.deskthemepack' -o -iname '*.dll' -o -iname '*.dmp' -o -iname '*.drv' -o -iname '*.icns' -o -iname '*.ico' -o -iname '*.lnk' -o -iname '*.sys' -o -iname '*.cfg' -o -iname '*.ini' -o -iname '*.prf' -o -iname '*.hqx' -o -iname '*.mim' -o -iname '*.uue' -o -iname '*.7z' -o -iname '*.cbr' -o -iname '*.deb' -o -iname '*.gz' -o -iname '*.pkg' -o -iname '*.rar' -o -iname '*.rpm' -o -iname '*.sitx' -o -iname '*.tarr' -o -iname '*.zip' -o -iname '*.zipx' -o -iname '*.bin' -o -iname '*.cue' -o -iname '*.dmg' -o -iname '*.iso' -o -iname '*.mdf' -o -iname '*.toast' -o -iname '*.vcd' -o -iname '*.c' -o -iname '*.class' -o -iname '*.cpp' -o -iname '*.cs' -o -iname '*.dtd' -o -iname '*.fla' -o -iname '*.h' -o -iname '*.java' -o -iname '*.lua' -o -iname '*.m' -o -iname '*.pl' -o -iname '*.py' -o -iname '*.sh' -o -iname '*.sln' -o -iname '*.vcxproj' -o -iname '*.xcodeproj' -o -iname '*.bak' -o -iname '*.tmp' -o -iname '*.crdownload' -o -iname '*.ics' -o -iname '*.msi' -o -iname '*.part' -o -iname '*.torrent' -o -iname '*.raw' -exec mv {} /home/malon/Desktop/test/ \;
If I leave out the -exec portion at the end of the find command, the find command works as expected. This leads me to believe it's something to do with exec, not the find part.
What this code is supposed to do:
Move any detected file up one level from ~/Desktop/test/all/ to ~/Desktop/test/
What this code actually does:
Nothing at all. No error. Looks successful, but the files are never moved.
Are you certain there's no typos?
Pretty certain, seeing as it works with a smaller number of arguments. I also build that command using a loop, lessening the chance of typos.
How did I build this command?
I wrote a bash script here: http://pastebin.com/MeQgH74X
Why have such a huge find command?
Because the actual folder I'm trying to get organized comes from a backup drive that has hundreds of thousands of folders (incremental backups) and iterating through it more than once is painfully long. I'd like to iterate the backup drive once, find the files I need as I go, move them all into a single folder, then iterate that single folder (now holding all the file types I want) and then place the files into folders based on filetype. I hope that makes sense.
Thanks guys!
Logical and has a higher precedence than logical or in find.
find ... \( ... -o ..... \) -exec ...

Resources