help-bash
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: [Help-bash] Replace empty files with real ones


From: Greg Wooledge
Subject: Re: [Help-bash] Replace empty files with real ones
Date: Mon, 13 May 2019 08:53:15 -0400
User-agent: Mutt/1.10.1 (2018-07-13)

On Sat, May 11, 2019 at 12:44:15AM +0200, James wrote:
> I'm in a nasty situation and I couldn't figure out how to solve this issue.
> A large number of my pictures are gone due to a badly written bash script.
> I could recover many of them but some are just empty files (with proper 
> names, though).
> Luckily, some pictures had been saved multiple places, and they had unique 
> file names.
> I was wondering if I could replace the empty files with regular images if 
> they have the very same file name?
> 
> For instance /mnt/recover/dir1/img007.jpg  file is empty but
> /home/user/Images/dir7/img007.jpg has content.
> (there can be many duplicates of img007.jpg elsewhere)
> 
> find /mnt/recover -type f -empty   found 20.000 files or so.

Where are these "multiple places" that the images can live?

When you say there "can be many duplicates of img007.jpg", does that mean
they're all identical files and you can choose any one of them from
among the non-empty files in the "multiple places"?  Or do you somehow
need to pick the "right one"?  How would that be determined -- timestamps?

I'm going to have to make some assumptions here.  It would be better if
things were spelled out explicitly.

Let's assume that you have:

1) One directory with empty files, all of which end in .jpg.  Using a
   recursive/hierarchical structure.

2) Three directories with non-empty files.  If a non-empty .jpg file
   found in any of these directories matches the name of an empty file
   in the first directory, copy it over the empty file.  Doesn't matter
   which non-empty file is used as long as the name matches.

So, here's the approach I would take:

1) Iterate over each of the three non-empty-file directories.  Store
   the pathnames of each .jpg file in an associative array indexed by
   the base filename.  E.g. file[img007.jpg]=/home/user/Images/dir7/img007.jpg

2) Once that array is populated, iterate over the directory with the empty
   files.  For each empty .jpg file, if an entry exists in the array, copy
   that pathname over the empty file.

Thus:

#!/bin/bash

dirs=(/home/user/Images /dir2 /another/directory)
empty=/mnt/recover
declare -A file

for d in "address@hidden"; do
  while IFS= read -rd '' f; do
    base="${f##*/}"
    file["$base"]="$f"
  done < <(find "$d" -type f -name '*.jpg' -print0)
done

while IFS= read -rd '' f; do
  base="${f##*/}"
  if [[ "${file["$base"]}" ]]; then
    printf 'copy <%s> <%s>\n' "${file["$base"]}" "$f"  # Comment me out later.
    # cp "${file["$base"]}" "$f"    # Uncomment me when you're sure it's safe.
  fi
done < <(find "$empty" -type f -name '*.jpg' -size 0 -print0)


This is untested, hence the printf instead of the live cp command.



reply via email to

[Prev in Thread] Current Thread [Next in Thread]