3

A previous question of mine asked how to pipe downloaded files through tar, now I would like to know how to pipe the output of tar through mv. See I have this command at the moment:

wget -c https://github.com/JeffHoogland/moksha/archive/0.1.0.tar.gz | tar -xz

and this creates a directory called moksha-0.1.0, but I would like to know how I might rename this output directory as moksha, perhaps via a pipe (|) at the end of this command. Although if you know how to do this without a pipe, but still on the same line of code as wget and tar, I will be happy to accept it too.

To be clear I know that:

wget -c https://github.com/JeffHoogland/moksha/archive/0.1.0.tar.gz | tar -xz -C moksha

will create an output directory moksha but within this output directory there will be the moksha-0.1.0 directory, rather I want to rename this moksha-0.1.0 directory as moksha, instead of placing moksha-0.1.0 in a new directory called moksha.

  • 7
    This is an XY Problem; you are asking about a proposed solution (piping to mv) rather than how to solve a problem (creating and renaming a file in a single command.) – Mathletics Nov 4 '15 at 12:47
  • 1
    Should be something such as "How do I rename a directory while extracting it from a tar file?". – deltab Nov 4 '15 at 15:35
8

Like this?

[root@b se]# wget -cqO - https://github.com/JeffHoogland/moksha/archive/0.1.0.tar.gz | tar -xz --transform=s/moksha-0.1.0/moksha/
[root@b se]# ls
moksha
[root@b se]# ls moksha
ABOUT-NLS       config.guess          debian                 Makefile.am
aclocal.m4      config.guess.dh-orig  depcomp                Makefile.in
AUTHORS         config.h.in           doc                    missing
autogen.sh      config.rpath          enlightenment.pc.in    netwm.txt
autom4te.cache  config.sub            enlightenment.spec.in  NEWS
BACKPORTS       config.sub.dh-orig    INSTALL                po
BUGS            configure             install-sh             README
ChangeLog       configure.ac          intl                   src
compile         COPYING               ltmain.sh              xdebug.sh
config          data                  m4                     x-ui.sh

From the tar manual page:

--transform=EXPRESSION, --xform=EXPRESSION
    Use sed replace EXPRESSION to transform file names.

So sed is probably required for this to work. Though if you have wget, you probably have sed as well.

5

Note: My answer isn't really about tar; it's an answer to this part of your question specifically:

...this creates a directory called moksha-0.1.0, but I would like to know how I might rename this output directory as moksha, perhaps via a pipe (|) at the end of this command. Although if you know how to do this without a pipe, but still on the same line of code as wget and tar, I will be happy to accept it too.

A pipe connects the standard output of one command with the standard input of the next. It doesn't have much to do with files—certainly not with moving files that are created by a previous command in a pipeline.

What you want is a list.

From man bash:

   AND  and  OR  lists are sequences of one of more pipelines separated by
   the && and ││ control operators, respectively.  AND and  OR  lists  are
   executed with left associativity.  An AND list has the form

          command1 && command2

   command2  is  executed if, and only if, command1 returns an exit status
   of zero.

The easiest way to do a simple if-then check for one command, or to make one command conditional on the success of another, is with &&. Examples:

[ -r somefile ] && cat somefile
# Checks if somefile exists and is readable; cats the file if it is.

sed -f sedscript inputfile > outputfile && mv outputfile inputfile
# One way (not the best) to edit a file in place.
# The point is that the second command only executes if the first command "succeeds" (i.e. returns a zero exit status).

So, for your specific command, just do:

(The whole command you wrote) && mv moksha-0.1.0 moksha
4

You can't pipe a file through mv, per se—mv doesn't read source files from standard input. In this case, your best bet is either getting tar to change the destination directory (as in Dee Eff's answer) or renaming it after the fact (as in Wildcard's answer).

My preference is for the former, but using -C and --strip-components instead of --transform:

mkdir moksha && wget -c https://github.com/JeffHoogland/moksha/archive/0.1.0.tar.gz |
  tar -xzC moksha --strip-components=1

(-C will not, in fact, create its argument—at least not on my system's BSD or GNU tars.)

This is more portable (the BSD tar has no --transform) and won't modify filenames that contain the string moksha-0.1.0 elsewhere—instead, it will simply remove the first component of the path of each file being extracted (e.g. moksha-0.1.0/ABOUT-NLS becomes just ABOUT-NLS). Because tar has changed to the new moksha directory, everything from the archive will be extracted there.

The archive you linked in your question has just one directory in its root, but it's important to note that using this technique on an archive with multiple directories in its root will dump all of the contents in those directories into the one directory specified by -C. In such cases, you would be better served extracting and then renaming as necessary.

  • 1
    For the record, you can modify just the first component of the path with --xform too; as it's sed syntax, you can modify pretty much any part of the path... – don_crissti Nov 4 '15 at 12:18

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

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