How to find files of certain extension and tar each of them in to another location

11,304

Solution 1

I'm going with...

cd /to/top/of/dir/structure
find . -type f ! -iname '*.log' -exec gzip -c {} \> /path/to/gzips/\`basename {}\`.gz \;

...but I haven't tested it.

And I'm really dubious it will be what you really need...


Edit

I can get it as far as...

find /path/to/top-level -iname "*.log" -printf "gzip -c %p > /path/to/gzips/%f.gz\n"

...to output the commands you would want to run.

I'm still working on executing those commands, short of -fprinting to a temp file, chmod +x and executing that.

Not to mention dealing with any issues escaping awkward characters in filenames.


Edit #2

OK, I can't get it down to one line (which was my challenge, not yours), but I can get it into a fairly simple script:

#!/bin/bash

function compress_file {
  BASENAME=`/bin/basename "$1"`;
  /bin/gzip -c "$1" > /path/to/gzips/$BASENAME.gz;
}

export -f compress_file;
/bin/find /path/to/top-level -iname "*.log" -exec /bin/bash -c 'compress_file "$0"' {} \;
export -fn compress_file;

Solution 2

Without a pipe (or xargs), creating several tar files instead of just one, and deleting the non-compressed files, here is how you can do it:

find /path/to/files -name "*.ext" -type f -exec tar -czf {}.tar.z {} \; -exec rm {} \;

Solution 3

Find the files and build a list, tell tar to make an archive from the list....

find /path/to/files -name "*.ext" | tar cJfTP /path/to/archive.txz -

Side note: your example doesn't compress the file, it just archives it.

Share:
11,304

Related videos on Youtube

FELDAP
Author by

FELDAP

Updated on September 18, 2022

Comments

  • FELDAP
    FELDAP almost 2 years

    I have script for finding files of certain type and compress them to a single tar archive and put in to other place. But now, there is a change in requirement, that I need to find files of certain type, list it and compress each of them to a tar archive and put it to other place. Currently I'm using the script

    cd /to/top/of/dir/structure
    tar -cf /path/to/tarfile.tar --files-from /dev/null # trick to create empty tar file
    find . -type f ! -name '*.log' -print0 | xargs -0 tar -uvf /path/to/tarfile.tar
    

    which I have taken from this post : https://superuser.com/questions/436441/copy-every-file-with-a-certain-extension-recursive

    So, the above script find certain file type and then archive it as single tar file and then place it to another location. But my question is, I need to find files of certain type, list them, tar each of the listed files and put them into other location.

    • user9517
      user9517 over 11 years
      What do you mean by list it?
    • FELDAP
      FELDAP over 11 years
      Like, finding the files of certain types and list them using stdout in console or store it in a file.
    • user9517
      user9517 over 11 years
      so you want to make a list of the files that you have put in the tar file ?
    • FELDAP
      FELDAP over 11 years
      No, after finding the files of certain type, I would like to list it and then tar each of the listed files to a certain location.
    • jimbobmcgee
      jimbobmcgee over 11 years
      ...but you are already doing that, no? Are you saying you want to handle multiple types of file? If so, add more find statements to your script -- they will be run sequentially
    • FELDAP
      FELDAP over 11 years
      Ok, files are listed. But the thing is, the above script will only make a single tar archive of all the listed files. But I need to make tar archive of each listed files. Hope you got my point :)
    • jimbobmcgee
      jimbobmcgee over 11 years
      A tar of each file (file1.tar, file2.tar,...,filen.tar)? Or a tar of each group of files (.log, *.tmp,...,.etc)?
    • FELDAP
      FELDAP over 11 years
      A tar of each file. (File.tar, tile2.tar, ...,filen.tar).
    • jimbobmcgee
      jimbobmcgee over 11 years
      Any particular reason? You know tar doesn't strictly compress, right (unless you add -z for a gzip file)? You might be better off with straight gzip for a per-file approach
    • FooBee
      FooBee over 11 years
      A tar of each file doesn't make any sense. If you want to compress the files, use gzip instead of tar.
    • FELDAP
      FELDAP over 11 years
      Ok. As per your recommendation, gzip is good. But how do I implement or modify the script to do so? I'm new to scripting.
  • FELDAP
    FELDAP over 11 years
    Thanks. But its not working. It produces some strange outputs in console in weird characters.
  • Valentin Bajrami
    Valentin Bajrami over 11 years
    This should work touch {file1,file2,file3,file4}.txt file10.log; find . ! -name '*.log' -type f -print0 | xargs -0 tar cvf tarr.tar {} \; 2>/dev/null
  • Hennes
    Hennes over 11 years
    That satisfies the Ops original goal. However after reading the dozens of comments on the OP it is clear that there is a new goal: bzipped copies of the log. (one file per log, not one big tar).
  • jimbobmcgee
    jimbobmcgee over 11 years
    Edited answer...
  • FELDAP
    FELDAP over 11 years
    Thanks.But it only lists the files, not compressing it.
  • jimbobmcgee
    jimbobmcgee over 11 years
    ...which is what I said in the edit. You would have to run the statements it returns to do the actual compression.
  • jimbobmcgee
    jimbobmcgee over 11 years
    OK, edited again...
  • Falcon Momot
    Falcon Momot almost 11 years
    Alas! I don't think very many of us speak French very well. I've tried to translate you, though. Feel free to edit it if my French is bad.
  • spuder
    spuder about 9 years
    I think 'tar.z' be 'tar.gz' since the .gz extension is more common.