Here's a possibility that will take the extracted files and move them to a subdirectory, cleaning up your main folder.
#!/usr/bin/perl -w
use strict;
use Getopt::Long;
my $clean_folder = "clean";
my $DRY_RUN;
die "Usage: $0 [--dry] [--clean=dir-name]\n"
if ( !GetOptions("dry!" => \$DRY_RUN,
"clean=s" => \$clean_folder));
# Protect the 'clean_folder' string from shell substitution
$clean_folder =~ s/'/'\\''/g;
# Process the "tar tv" listing and output a shell script.
print "#!/bin/sh\n" if ( !$DRY_RUN );
while (<>)
{
chomp;
# Strip out permissions string and the directory entry from the 'tar' list
my $perms = substr($_, 0, 10);
my $dirent = substr($_, 48);
# Drop entries that are in subdirectories
next if ( $dirent =~ m:/.: );
# If we're in "dry run" mode, just list the permissions and the directory
# entries.
#
if ( $DRY_RUN )
{
print "$perms|$dirent\n";
next;
}
# Emit the shell code to clean up the folder
$dirent =~ s/'/'\\''/g;
print "mv -i '$dirent' '$clean_folder'/.\n";
}
Save this to the file fix-tar.pl
and then execute it like this:
$ tar tvf myarchive.tar | perl fix-tar.pl --dry
This will confirm that your tar
list is like mine. You should get output like:
-rw-rw-r--|batch
-rw-rw-r--|book-report.png
-rwx------|CaseReports.png
-rw-rw-r--|caseTree.png
-rw-rw-r--|tree.png
drwxrwxr-x|sample/
If that looks good, then run it again like this:
$ mkdir cleanup
$ tar tvf myarchive.tar | perl fix-tar.pl --clean=cleanup > fixup.sh
The fixup.sh
script will be the shell commands that will move the top-level files and directories into a "clean" folder (in this instance, the folder called cleanup
). Have a peek through this script to confirm that it's all kosher. If it is, you can now clean up your mess with:
$ sh fixup.sh
I prefer this kind of cleanup because it doesn't destroy anything that isn't already destroyed by being overwritten by that initial tar xv
.
Note: if that initial dry run output doesn't look right, you should be able to fiddle with the numbers in the two substr
function calls until they look proper. The $perms
variable is used only for the dry run so really only the $dirent
substring needs to be proper.
One other thing: you may need to use the tar
option --numeric-owner
if the user names and/or group names in the tar
listing make the names start in an unpredictable column.
xargs
(tac
instead ofsort -r
is just cosmetics), but you accept the answer with process substitution that, as you explained in the comments, did not fit you? Also, please give thexargs -d'\n'
switch in your post if you want to summarize for future users, so they won't get bitten by spaces in file names.-d'\n'
until now, and upon further analysis your answer is actually closer to what I used.-d'\n'
lies in the fact that if you don't tellxargs
to split arguments on new lines (which is what you're feeding) but on spaces, then a file with the namefolder1/some file
will be read asfolder1/some
andname
.