20

This may be a simple question, but how do I use files starting with "-" with command line programs?

For example, I am trying to use pdfgrep on a file named -2013-01-01.pdf but it complains that there are no options defined for 2, 0, 1, 3 and so on.

Changing the filename to something that does not start with "-" solves it, but this is not an option since the files aren't created by me. I simply want to check for a specific change I know is coming.

muru
  • 193,181
  • 53
  • 473
  • 722
Kristoffer
  • 365
  • 1
  • 9
  • this dos not work, gives me the same errors as before – Kristoffer Apr 04 '13 at 23:41
  • 3
    As an example, `grep -i dfv -- -myfile1 -myfile2`. –  Apr 04 '13 at 23:42
  • that works! thanks! make it n answer and i can mark it as accepted for future generations :) – Kristoffer Apr 04 '13 at 23:47
  • @AliNa, did using quotes work for you with pdfgrep specifically? It didn't work for me. I'm using Lubuntu. –  Apr 05 '13 at 03:15
  • 4
    @AliNa: Quotation marks won't work, as they are interpreted by the shell, not the program. – hammar Apr 05 '13 at 04:08
  • @AliNa [Quotation marks don't make it work with `cp`, `cd`, or `rm` either.](http://paste.ubuntu.com/8594167/) When the shell sees `"-2013-01-01.pdf"`, the argument it passes to a command is still simply `-2013-01-01.pdf`. See [3.1.2 Quoting](https://gnu.org/software/bash/manual/bash.html#Quoting) and [3.5.9 Quote Removal](https://gnu.org/software/bash/manual/bash.html#Quote-Removal) for details. – Eliah Kagan Oct 19 '14 at 22:13
  • Yeah, I was wrong. So I'll delete my comments to prevent misinforming others. – AliNajafies Oct 20 '14 at 06:29

2 Answers2

22

Very frequently -- is used on the command-line to signal to a program that no more available command switches are going to be used. This is particularly useful if a file contains a dash, which the program would try to interpret as an option.

  1. Without the --, there is an error generated:

    $ pdfgrep -i posix -find.pdf -xorg.pdf
    
    pdfgrep: invalid option -- 'f'
    pdfgrep: invalid option -- 'd'
    pdfgrep: invalid option -- '.'
    pdfgrep: invalid option -- 'p'
    pdfgrep: invalid option -- 'd'
    pdfgrep: invalid option -- 'f'
    
  2. With the -- used we have a successful command:

    $ pdfgrep -i posix -- -find.pdf -xorg.pdf
    
    -find.pdf: on the command line. Currently-implemented types are emacs (this is the default), posix-awk,
    -find.pdf: posix-basic, posix-egrep and posix-extended.
    -find.pdf: posix-basic, posix-egrep and posix-extended.
    -find.pdf: posix-basic, posix-egrep and posix-extended.
    
  3. pdfgrep is programmed to understand -- to mean that the following command-line arguments are not options. Most programs do the same, but not all programs understand --. For programs that don't, the solution is to prepend the filename with ./, like this:

     pdfgrep -i posix ./-find.pdf ./-xorg.pdf
    

    This should work with any command, unless for some reason the command cannot accept a path, only a pure filename.

For a general introduction to the command-line, see this useful PDF.

Flimm
  • 40,306
  • 22
  • 94
  • 154
  • 4
    Unfortunately, `--` does **not** work with *all* command-line programs. I had assumed from [that comment by the OP](http://askubuntu.com/questions/278000/how-to-use-commands-with-input-filename-starting-with-character/278003?noredirect=1#comment348923_278000) that `pdfgrep` is one of them that doesn't recognize `--`. But the accept here suggests otherwise. In any case, a program must be coded to recognize `--`. Many programs use libraries to parse their arguments, which do recognize `--`. But some don't, and of those, some are not coded to recognize `--`. – Eliah Kagan Apr 05 '13 at 00:10
  • 3
    For those programs that do not recognise `--` the usual workaround is putting `./` in front of the file: `pdfgrep ./-2013-01-01.pdf` – Carlos Campderrós Apr 05 '13 at 06:51
  • 2
    Yes, putting `./` in front is the most portable and robust solution. Works on any program, on any unix version. – hlovdal Apr 05 '13 at 07:38
16

You prepend the file name with ./ (or another relative or absolute path that works). This way it's portable.

Example:

for zefile in ./*.tmp
do
   rm -f "$zefile"
done

The use of -- to indicate the end of options is not always available. Some commands will know it, some won't. And this will change across different systems. So in the end, it's less portable.

dessert
  • 39,392
  • 12
  • 115
  • 163
Olivier Dulac
  • 996
  • 4
  • 10