40

In a bash shell, when I have to remove multiple files in the same directory, I currently need to do something like this:

rm /some/path/file1 /some/path/file2

Is there a shorter way to write this so I don't have to retype /some/path/ without using a variable or changing the working directory?

Perhaps something similar to:

rm /some/path/(file1,file2)

4 Answers4

63

You're close:

rm /some/path/{file1,file2}

or even

rm /some/path/file{1,2}

Related, and supported by other shells, is a pattern like

rm /some/path/file[12]

The first two are expanded to two explicit file name arguments; the third is a pattern against which all files in /some/path are matched.

chepner
  • 7,501
9

Alternatively you can take advantage of the Readline library in Bash. This is a bit of a workaround, but relatively easy to type.

  1. ls /some/path/
  2. rm ESC.file1 ESC.file2

(Assuming your meta prefix is the ESC key.)

The extra ls in the first command puts the path in the history as the last argument of the previous command, ESC. (or as the manual states M-. or even M-_):

Insert[s] the last argument to the previous command (the last word of the previous history entry).

Thus you're effectively typing the last path before the file names. (Please note the trailing slash in the ls line).

lgarzo
  • 646
3

In addition to those insightful answers, there's numerous patterns you can use to match groups of files. With filename expansion and pattern matching, you can tell bash to match things like all files in a directory, all files starting with something, all files with the same extension, etc.

Of course, if your using rm, you have to be very careful not to delete things you don't want to. I recommend using ls first, to list what the path argument will show.

Here's a few examples.

  1. Say you want to match all files in a directory, to look at what an rm command would process, look with ls. You could use the asterisk (*) glob operator to match any amount of characters.

    ls /some/path/*
    
  2. Or maybe all files starting with test:

    ls /some/path/test*`
    
  3. How about all files starting with test, with one character, and ending with a .sh. You could use the question mark (?) character to match one character.

    ls /some/path/test?.sh
    
  4. Let's say you have nine files test1.sh, test2.sh, etc, up to test9.sh, and want to delete these test scripts. You also have a testa.sh you want to keep. You could search for all files starting with test, the numbers one through nine or non-alphabetic classes, and ending with .sh. These use the brackets ([]) to match groups of characters.

    ls /some/path/test[1-9].sh
    ls /some/path/test[!:alpha:].sh
    

Matches such as these can be scripted fairly simply too, enabling very fine tuned or broad groupings of files within scripts for automation.

Anthon
  • 79,293
0

If you use bash, you can make M-r repeat the last argument by adding this line to ~/.inputrc:

"\er": "!#:$\e^"

!# is the current line, $ is the last argument, and \e^ is history-expand-line.

Lri
  • 5,223