Take the 2-minute tour ×
Unix & Linux Stack Exchange is a question and answer site for users of Linux, FreeBSD and other Un*x-like operating systems.. It's 100% free, no registration required.

I've been working on this far too long and need some help. I need a script that will look at files in a directory and see if it exists in one of several directories.

I need something like this:

for files in /downloads/ #may or may not be in a sub-directory
do
   print if file exists in /media/tv, /media/movie, or /media/music
done

the files will not be in the root of the directory. I cant just search /media, because I don't want to search in cd-rom or videos

I am using the latest version of Ubuntu server

share|improve this question

5 Answers 5

You don't mention if you need to keep the files (perhaps removing duplicates?), hardlink them or anything else.

So, depending on your intention, the best solution would be to use one program like rdfind (not interactive), fdupes (more interactive, allowing you to choose which files to keep or not), duff (to only report the files that were duplicate) or many others.

If you want something fancier with a GUI that will let you choose what to keep via a point-and-click interface, then fslint (via its fslint-gui command) would be my recommended choice.

All of the above are available in Debian's repository and, by transition, I think that they are in Ubuntu's or Linux Mint's repositories, if that's what you are using.

share|improve this answer
    
The goal is to find files that i have downloaded, but have not yet copied to my media directory. Although finding duplicates will be a nice way to clean up my collection, its not what I'm looking to do in this script. –  andrew.vh Nov 13 '12 at 19:40
    
@andrew.vh, any of the utilities above would catch files with the same names, as they, more generally, will look for the contents of the files, not just their names, as you already noticed. –  rbrito Nov 14 '12 at 15:05

Here is an implementation in bash using brace expansion:

the_file=foo.mp3
for file in /downloads/media/{tv,movie,music}/"$the_file"; do 
   if [[ -e $file ]]; then
      printf '%s found in %s:\n' "$the_file" "${file%/*}"
   fi
done
share|improve this answer
1  
As I understand it, /media/ is not a subfolder of /downloads/ –  Bernhard Nov 13 '12 at 7:07
1  
The original poster didn't mention it, but your method essentially only looks at the file names, not at the file contents. Which is the original poster's intention is not clear, though. –  rbrito Nov 13 '12 at 16:05
    
Bernhard is correct, they are not in a subfolder of downloads. –  andrew.vh Nov 13 '12 at 19:32
1  
also I didnt realize you could compare files based on contents. that would be nice as sometimes I would like to rename the files. –  andrew.vh Nov 13 '12 at 19:33

This could be very slow if you traverse /downloads or /media for each file name. So traverse each hierarchy only once, store the list of file names, and then process the lists.

For simplicity, I assume that your file names don't contain any newlines.

find /downloads -type f | sed 's!^.*/\(.*\)$!\1/&!' |
  sort >/tmp/downloads.find
find /media/tv /media/music /media/movie -type f |
  sed 's!^.*/\(.*\)$!\1/&!' |
  sort >/tmp/media.find

At this point, the two .find files contain lists of file paths, with the name of the file prepended, sorted by file name. Join the files on the first /-separated field, and clean up the result a bit.

join -j 1 -t / /tmp/downloads.find /tmp/media.find |
  sed -e 's![^/]*/!!' -e 's![^/]*/! has the same name as !'
share|improve this answer
    
This is the join command that worked for me: join -j 1 -t / /tmp/downloads.find /tmp/media.find | sed -e 's![^/]*/!!' -e 's!//! has the same name as /!' (tested on two computers running SLES 10 and 11.) –  jaume Nov 15 '12 at 9:56
echo "Enter file name"
read file
flag=0

for i in 'ls'
do
  if [ $i == $file ] ;then
    echo "File exist"
    flag=1
    break;
  fi
done

if [ $flag == 0 ] ;then
  echo "File not exist"
fi
share|improve this answer
1  
That only checks in the current directory... –  vonbrand Apr 8 '13 at 17:02
chk='/[m]edia'
for f in $chk/movies/file $chk/tv/file $chk/music/file
do  [ -z "${f##"$chk"*}" ] ||
    printf %s\\n "$f exists!"
done

You can glob against a known value and check its results for resolution.

share|improve this answer

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.