8

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.

marked as duplicate by Sergiy Kolodyazhnyy, muru, don_crissti, Jeff Schaller, Stéphane Chazelas bash Dec 16 '18 at 15:41

This question has been asked before and already has an answer. If those answers do not fully address your question, please ask a new question.

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.

  • Loved “$_” didn’t knew about it! Thanks a lot for your contribution, well put! – Marco Dec 15 '18 at 17:58
4

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

tar xvf test.tar.gz
rm !$
  • What does it do in general? Is it similar to $_? – Solomon Ucko Dec 16 '18 at 13:01
  • it inserts last argument from last command in history. – RiaD Dec 16 '18 at 19:17
  • Do you know what the difference between !$ and $_ is? – Solomon Ucko Dec 16 '18 at 19:18
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.

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