9

For example:

tar xvf test.tar.gz ;  rm test.tar.gz

Is there a faster way to reference the file name on the second execution?

I was thinking something like this (which is invalid):

tar xvf test.tar.gz ; rm $1

Anything possible?

I'm fully aware of wildcards.

  • Or https://unix.stackexchange.com/questions/139202/reuse-similar-flags-for-multiple-commands, https://unix.stackexchange.com/questions/136599/run-two-commands-on-one-argument-without-scripting – muru Dec 16 '18 at 05:09

4 Answers4

19

You could assign the filename to a variable first:

f=test.tar.gz; tar xvf "$f"; rm "$f"

Or use the $_ special parameter, it contains the last word of the previous command, which is often (but of course not always) the filename you've been working with:

tar xvf test.tar.gz; rm "$_"

This works with multiple commands too, as long as the filename is always the last argument to the commands (e.g. echo foo; echo $_; echo $_ prints three times foo.)

As an aside, you may want to consider using tar ... && rm ..., i.e. with the && operator instead of a semicolon. That way, the rm will not run if the first command fails.

ilkkachu
  • 138,973
4

You can use !$ if you move the second command to a new line.

tar xvf test.tar.gz
rm !$
guntbert
  • 1,637
RiaD
  • 151
3

In bash version above 4, you can use history expansion to reference the nth positional parameter of the current command. For instance, in tar xvf test.tar.gz that is 2nd positional parameter to the command, thus the command can be reduced to

tar xvf test.tar.gz && rm !#:2

Another, more portable way ( tested with /bin/dash ) is to use $_ variable to reference last positional parameter:

tar xvf test.tar.gz && rm "$_"

See also How do I execute multiple commands using the same argument?

0

if you ever used a loop to process multiple files, then you were already using a way that you can also use for just one file:

for i in a.tgz b.tgz c.tgz; do tar xvf $i; rm $i; done

for one file:

for i in a.tgz; do tar xvf $i; rm $i; done

i find this solution noteworthy because this for loop is a common pattern that you may already be using, but have not thought to apply to this question. it didn't come to my mind either when i initially thought it.

eMBee
  • 532
  • 4
  • 7