391

I'm trying to check if a file exists, but with a wildcard. Here is my example:

if [ -f "xorg-x11-fonts*" ]; then
    printf "BLAH"
fi

I have also tried it without the double quotes.

Peter Mortensen
  • 30,738
  • 21
  • 105
  • 131
Danny
  • 5,180
  • 6
  • 26
  • 29
  • 24
    Two bugs with your code: (1) The asterisk has to be outside the double quotes (a quoted asterisk loses it special wildcard meaning), and (2) if multiple files match the pattern, multiple arguments will be passed to the `[` command, most likely causing `[` to exit with an error and therefore be interpreted as no files matching. – Richard Hansen Jun 17 '11 at 06:31

21 Answers21

604

For Bash scripts, the most direct and performant approach is:

if compgen -G "${PROJECT_DIR}/*.png" > /dev/null; then
    echo "pattern exists!"
fi

This will work very speedily even in directories with millions of files and does not involve a new subshell.

Source


The simplest should be to rely on ls return value (it returns non-zero when the files do not exist):

if ls /path/to/your/files* 1> /dev/null 2>&1; then
    echo "files do exist"
else
    echo "files do not exist"
fi

I redirected the ls output to make it completely silent.


Here is an optimization that also relies on glob expansion, but avoids the use of ls:

for f in /path/to/your/files*; do

    ## Check if the glob gets expanded to existing files.
    ## If not, f here will be exactly the pattern above
    ## and the exists test will evaluate to false.
    [ -e "$f" ] && echo "files do exist" || echo "files do not exist"

    ## This is all we needed to know, so we can break after the first iteration
    break
done

This is very similar to grok12's answer, but it avoids the unnecessary iteration through the whole list.

Peter Mortensen
  • 30,738
  • 21
  • 105
  • 131
Costi Ciudatu
  • 37,042
  • 7
  • 56
  • 92
  • 9
    A word of warning: In the Debian Almquist Shell (`dash`) — installed at `/bin/sh` in Debian and Ubuntu — `&>` seems to discard the exit code and that breaks this solution. A workaround is to redirect with `> /dev/null 2>&1` instead. – qerub Nov 20 '11 at 18:42
  • 21
    `ls` can be quite slow on a directory with many files (probably due to sorting). You may want to turn off sorting with `-U`, at least. – musiphil Jun 21 '12 at 21:01
  • Would it be better to list the files into text file and look at that if you were dealing with a lot of searches? – Mike Q Jun 13 '14 at 16:35
  • @musiphil Thanks for the input. I edited the answer to add an optimized alternative which eliminates the use of `ls`. – Costi Ciudatu Sep 27 '14 at 14:57
  • 1
    @CostiCiudatu have you checked how that alternative works when there are spaces in the directory name? Wouldn't e.g. `for f in /path/to/your files*` interpreted as two arguments, `/path/to/your` and `files*`? I've tried putting double-quotes around, but that didn't work out (never finds a file, even if there's one). – Izzy Dec 13 '14 at 21:00
  • 6
    @Izzy, you are supposed to put that in double quotes, but leave the `*` outside: `for f in "/path/to/your files"*` should work. – Costi Ciudatu Dec 13 '14 at 23:02
  • 1
    @CostiCiudatu confirmed, thanks! You might wish to include that with your answer to make it easier to find :) I meanwhile settled with [Pankaj's answer](http://stackoverflow.com/a/17404812/2533433) – but good to know an alternative :) – Izzy Dec 13 '14 at 23:16
  • 2
    Warning. This will fail if the directory contains a lot of files. The expansion of "*" will exceed the command line length limit. – Chris Cogdon Jul 29 '16 at 23:35
  • @CostiCiudatu however it will still fail if the files themselves have spaces within their names, won't it? – Fabio A. Nov 25 '16 at 14:45
  • I posted a solution that doesn't require any `for` loops, neither any external tools, and works with file names containing spaces: http://stackoverflow.com/a/40808284/566849 – Fabio A. Nov 25 '16 at 15:37
  • One side note... Not all linux/unix boxes support `glob`. For instance, one of the unix servers at my work doesn't support `glob`. – Sometowngeek Sep 17 '18 at 18:26
  • The second option without the conditional first will not work with `set -e` enabled (often enabled on build systems to make bash fail immediately on errors). In this case the script might fail undesirably when it encounters the for-loop. – Jonathan Komar Nov 04 '19 at 09:05
  • 1
    https://unix.stackexchange.com/questions/128985/why-not-parse-ls-and-what-to-do-instead – qwr Jan 22 '20 at 18:59
  • Use `if ! compgen -G "${PROJECT_DIR}/*.png" > /dev/null; then` – Theodore R. Smith Oct 14 '20 at 22:09
  • `compgen -G` does not quite seem to support advanced glob patterns. Does not work with `compgen -G "*.{ts,go,json}"`. That is, the -G globbing logic and the _actual_ globbing logic are not always the same (at least not w/o additional care?). Seems brittle. – Dr. Jan-Philip Gehrcke Dec 08 '20 at 15:21
  • 1
    @TheodoreR.Smith I don't feel comfortable taking credit for your awesome solution, so please consider reverting your edit and making that an answer of your own or a comment instead of editing an old accepted answer. – Costi Ciudatu Dec 08 '20 at 19:00
  • What is the purpose of the `1` after the ls command and before sending it to /dev/null? I guess it is redundant? Or good practice? – Amit Nayar Aug 16 '23 at 08:34
80

If your shell has a nullglob option and it's turned on, a wildcard pattern that matches no files will be removed from the command line altogether. This will make ls see no pathname arguments, list the contents of the current directory and succeed, which is wrong. GNU stat, which always fails if given no arguments or an argument naming a nonexistent file, would be more robust. Also, the &> redirection operator is a bashism.

if stat --printf='' /path/to/your/files* 2>/dev/null
then
    echo found
else
    echo not found
fi

Better still is GNU find, which can handle a wildcard search internally and exit as soon as at it finds one matching file, rather than waste time processing a potentially huge list of them expanded by the shell; this also avoids the risk that the shell might overflow its command line buffer.

if test -n "$(find /dir/to/search -maxdepth 1 -name 'files*' -print -quit)"
then
    echo found
else
    echo not found
fi

Non-GNU versions of find might not have the -maxdepth option used here to make find search only the /dir/to/search instead of the entire directory tree rooted there.

flabdablet
  • 3,565
  • 3
  • 22
  • 15
  • 7
    Letting `find` handle the wildcard is best because `bash`, as it expands the pattern, tries to sort the list of the matching file names, which is wasteful and can be expensive. – musiphil Jun 21 '12 at 21:10
  • 3
    @musiphil Launching an external process such as `find` is even more wasteful if there are only a few files (or none) in the directory. – dolmen Feb 24 '17 at 16:46
  • @dolmen: You are right. I guess it all depends on the situation; on the other hand, if there are a huge number of files, the wildcard expansion of `bash` can take more time than launching `find`. – musiphil Mar 13 '17 at 18:48
  • @musiphil Even worse: if there is a huge number of the wildcard expansion can simply fail. But in that case, expanding the huge output of `find` will probably fail too. Note also that listing all files with find just to then test if that output is empty or not is a big waste of resources. – dolmen Apr 13 '17 at 07:41
  • 1
    The find command creates an ugly error message if no files are found: `find: '/dir/to/search': No such file or directory` ; You can suppress this with `-quit 1> /dev/null 2>&1` – rubo77 Apr 23 '17 at 11:26
  • 3
    @dolmen: Running `find` with `-quit` as described in @flabdablet's post will not suffer from a huge number of files, because it quits as soon as it finds the first match and thus will not list all files. So it is not as big a waste of resources as you suggest. Moreover, `find` doesn't simply "expand" the wildcard as the shell does, but checks each file it finds against the pattern to see if it is a match, so it doesn't fail for a huge number of files. – musiphil Apr 25 '17 at 01:34
42

Use:

files=(xorg-x11-fonts*)

if [ -e "${files[0]}" ];
then
    printf "BLAH"
fi
Peter Mortensen
  • 30,738
  • 21
  • 105
  • 131
Pankaj Parashar
  • 9,762
  • 6
  • 35
  • 48
35

You can do the following:

set -- xorg-x11-fonts*
if [ -f "$1" ]; then
    printf "BLAH"
fi

This works with sh and derivatives: KornShell and Bash. It doesn't create any sub-shell. $(..) and `...` commands used in other solutions create a sub-shell: they fork a process, and they are inefficient. Of course it works with several files, and this solution can be the fastest, or second to the fastest one.

It works too when there aren't any matches. There isn't a need to use nullglob as one of the commentators say. $1 will contain the original test name, and therefore the test -f $1 won't success, because the $1 file doesn't exist.

Peter Mortensen
  • 30,738
  • 21
  • 105
  • 131
joseyluis
  • 537
  • 4
  • 10
  • 1
    The most portable solution! – dolmen Feb 24 '17 at 17:03
  • 1
    Alas, it doesn't work when there's no matches. $1 will contain the original test name, including the *. You could set "nullglob" in bash so it WILL blank out. THat's not portable, though :) – Chris Cogdon Mar 09 '18 at 20:55
  • Chris, when there isn't a match, $1 will contain the origintal test name, including the * as you say. Then the test: [ -f "$1" ] won't be sucessfull because the file "*" doesn't exist. Therefore you don't need nullglob, or other tricks. It is 100% portable. – joseyluis May 16 '18 at 09:59
  • Tried with zsh as shell. It works if typed as a command, but fails with 'no matches found' when called from a zsh script. (Strangely) – jmary May 29 '19 at 12:36
  • 1
    jmary: Which set command did you use? Some special character? – joseyluis May 29 '19 at 12:41
  • This is the best answer! – Nelson Rodriguez Oct 15 '21 at 20:49
  • @jmary the answer does not claim it works with zsh, and trully it doesn't... however: `noglob set -- *pyz ; { test -f "$1" && echo got $1 ; } || echo no file` – Ярослав Рахматуллин Apr 20 '22 at 10:00
25
for i in xorg-x11-fonts*; do
  if [ -f "$i" ]; then printf "BLAH"; fi
done

This will work with multiple files and with white space in file names.

tripleee
  • 175,061
  • 34
  • 275
  • 318
grok12
  • 3,526
  • 6
  • 26
  • 27
  • 6
    It will print multiple "BLAH" if there are multiple matches. Maybe add a `break` to exit the loop after the first match. – tripleee May 27 '16 at 18:19
  • 2
    This (with @tripleee ‘s break) gets my vote. By using only native globbing and the file test operator, it avoids even raising the question of corner cases, that comes with using commands like ls or find or from forwarding globs. I think it is free of all the issues, like names with blanks, nullglob setting and bashisms, that were raised for some other answers. I made a function of it: `existsAnyFile () { for file; do [ -f "$file" ] && return 0; done; false; }` – sdenham Jun 30 '16 at 15:49
  • Note this gets a stat failure if xorg-x11-fonts* does not exist, which is probably not what you want. – rfay Nov 08 '18 at 23:04
20

The solution:

files=$(ls xorg-x11-fonts* 2> /dev/null | wc -l)
if [ "$files" != "0" ]
then
   echo "Exists"
else
    echo "None found."
fi

> Exists
Peter Mortensen
  • 30,738
  • 21
  • 105
  • 131
Swift
  • 13,118
  • 5
  • 56
  • 80
  • In my shell (zsh) it works if there is only one match to the glob, otherwise it expands all the files and the test fails (too many arguments.) – Edward Thomson Jun 15 '11 at 20:02
  • 1
    Update my code. I'm sure this works, I just installed zsh and tested. – Swift Jun 15 '11 at 20:20
  • 2
    `ls` can be quite slow on a directory with many files (probably due to sorting). You may want to turn off sorting with `-U`, at least. – musiphil Jun 21 '12 at 21:01
  • If the globbing matches a directory name, ls will spit out the contentes of that directory which may cause false positives. – William Everett Mar 21 '16 at 22:00
  • Running `ls` and `wc` require to launch two external programs. Not efficient at all. – dolmen Feb 24 '17 at 16:53
15

Use:

if [ "`echo xorg-x11-fonts*`" != "xorg-x11-fonts*" ]; then
    printf "BLAH"
fi
Peter Mortensen
  • 30,738
  • 21
  • 105
  • 131
Marian
  • 7,402
  • 2
  • 22
  • 34
  • 2
    This is **the simplest, easiest and most elegant answer** that actually works! – Serge Stroobandt Jun 28 '15 at 14:00
  • 4
    @SergeStroobandt Not sure I agree. The command substitution may be necessary here, but it tickles my cringe reflex. – tripleee May 27 '16 at 18:21
  • 2
    yea... like what if the file with the literal name `xorg-x11-fonts\*` exists? – mlathe Oct 12 '16 at 18:32
  • 3
    Not elegant at all because it forks a sub shell to run the echo command. – dolmen Feb 24 '17 at 16:52
  • I think this solution is good when looking for files with extensions *.MIF – Faris Feb 12 '21 at 09:05
  • This didn't work for me. It evaluated to true regardless of file presence. What did work however was a combination of this trick with `-f` check: ```if [[ -f `echo ./logfile-*.log` ]]; then echo "has log"; fi```. **UPDATE** works with only one file though :( – n1kk Aug 22 '23 at 11:43
9

The PowerShell way - which treats wildcards different - you put it in the quotes like so below:

If (Test-Path "./output/test-pdf-docx/Text-Book-Part-I*"){
  Remove-Item -force -v -path ./output/test-pdf-docx/*.pdf
  Remove-Item -force -v -path ./output/test-pdf-docx/*.docx
}

I think this is helpful because the concept of the original question covers "shells" in general not just Bash or Linux, and would apply to PowerShell users with the same question too.

Peter Mortensen
  • 30,738
  • 21
  • 105
  • 131
Jeremy Hajek
  • 201
  • 1
  • 4
  • 12
9

The Bash code I use:

if ls /syslog/*.log > /dev/null 2>&1; then
   echo "Log files are present in /syslog/;
fi
Peter Mortensen
  • 30,738
  • 21
  • 105
  • 131
CapitanBlack
  • 91
  • 1
  • 2
  • An explanation would be in order. E.g., what is the principle of operation? What are the performance characteristics (process start overhead, memory, scalability, etc.)? Please respond by [editing (changing) your answer](https://XXXX), not here in comments (***without*** "Edit:", "Update:", or similar - the answer should appear as if it was written today). – Peter Mortensen Nov 03 '21 at 00:56
  • Yeah, whatever, picky, picky, need performance, principals. This worked on positive and negative cases, others, not so much. Caveat: zsh on MacOS. – Michael Bushe Jun 05 '22 at 03:01
8

Strictly speaking, if you only want to print "Blah", here is the solution:

find . -maxdepth 1 -name 'xorg-x11-fonts*' -printf 'BLAH' -quit

Here is another way:

doesFirstFileExist(){
    test -e "$1"
}

if doesFirstFileExist xorg-x11-fonts*
then printf "BLAH"
fi

But I think the most optimal is as follows, because it won't try to sort file names:

if [ -z $(find . -maxdepth 1 -name 'xorg-x11-fonts*' -printf 1 -quit) ]
then 
     printf "BLAH"
fi
peppapig450
  • 62
  • 1
  • 5
Vouze
  • 1,678
  • 17
  • 10
  • You can also use `-exec` option of find like this: `find . -maxdepth 1 -name '*.o' -exec rm {} \;` – Megidd Mar 14 '18 at 07:49
6

Here's a solution for your specific problem that doesn't require for loops or external commands like ls, find and the like.

if [ "$(echo xorg-x11-fonts*)" != "xorg-x11-fonts*" ]; then
    printf "BLAH"
fi

As you can see, it's just a tad more complicated than what you were hoping for, and relies on the fact that if the shell is not able to expand the glob, it means no files with that glob exist and echo will output the glob as is, which allows us to do a mere string comparison to check whether any of those files exist at all.

If we were to generalize the procedure, though, we should take into account the fact that files might contain spaces within their names and/or paths and that the glob char could rightfully expand to nothing (in your example, that would be the case of a file whose name is exactly xorg-x11-fonts).

This could be achieved by the following function, in bash.

function doesAnyFileExist {
   local arg="$*"
   local files=($arg)
   [ ${#files[@]} -gt 1 ] || [ ${#files[@]} -eq 1 ] && [ -e "${files[0]}" ]
}

Going back to your example, it could be invoked like this.

if doesAnyFileExist "xorg-x11-fonts*"; then
    printf "BLAH"
fi

Glob expansion should happen within the function itself for it to work properly, that's why I put the argument in quotes and that's what the first line in the function body is there for: so that any multiple arguments (which could be the result of a glob expansion outside the function, as well as a spurious parameter) would be coalesced into one. Another approach could be to raise an error if there's more than one argument, yet another could be to ignore all but the 1st argument.

The second line in the function body sets the files var to an array constituted by all the file names that the glob expanded to, one for each array element. It's fine if the file names contain spaces, each array element will contain the names as is, including the spaces.

The third line in the function body does two things:

  1. It first checks whether there's more than one element in the array. If so, it means the glob surely got expanded to something (due to what we did on the 1st line), which in turn implies that at least one file matching the glob exist, which is all we wanted to know.

  2. If at step 1. we discovered that we got less than 2 elements in the array, then we check whether we got one and if so we check whether that one exist, the usual way. We need to do this extra check in order to account for function arguments without glob chars, in which case the array contains only one, unexpanded, element.

Fabio A.
  • 2,517
  • 26
  • 35
  • 1
    This is inefficient because `$(..)` launches a sub-shell. – dolmen Feb 24 '17 at 16:59
  • 1
    @dolmen a sub-shell is just a process like any other. The accepted answer launches the `ls` command, which for all intent and purposes is as efficient (or inefficient) as a sub-shell is. – Fabio A. Mar 28 '17 at 09:31
  • I've never written that the accepted answer is better and that I would have accepted if I had been the submitter. – dolmen Apr 13 '17 at 07:34
  • Notice that the generalized method I explain in this very same answer **doesn't** use any subshell at all. – Fabio A. Apr 13 '17 at 11:21
3

I found a couple of neat solutions worth sharing. The first still suffers from "this will break if there are too many matches" problem:

pat="yourpattern*" matches=($pat) ; [[ "$matches" != "$pat" ]] && echo "found"

(Recall that if you use an array without the [ ] syntax, you get the first element of the array.)

If you have "shopt -s nullglob" in your script, you could simply do:

matches=(yourpattern*) ; [[ "$matches" ]] && echo "found"

Now, if it's possible to have a ton of files in a directory, you're pretty well much stuck with using find:

find /path/to/dir -maxdepth 1 -type f -name 'yourpattern*' | grep -q '.' && echo 'found'
Peter Mortensen
  • 30,738
  • 21
  • 105
  • 131
Chris Cogdon
  • 7,481
  • 5
  • 38
  • 30
2

I use this:

filescount=`ls xorg-x11-fonts* | awk 'END { print NR }'`  
if [ $filescount -gt 0 ]; then  
    blah  
fi
  • 3
    `wc -l` is more efficient than `awk` for this task. – dolmen Feb 24 '17 at 16:57
  • 2
    Counting the number of results is an antipattern anyway. Usually you simply want to see whether `ls` returned success or not (or better yet avoid `ls` too and use the shell's built-in functionality). – tripleee Sep 26 '17 at 09:10
2

Using new fancy shmancy features in KornShell, Bash, and Z shell shells (this example doesn't handle spaces in filenames):

# Declare a regular array (-A will declare an associative array. Kewl!)
declare -a myarray=( /mydir/tmp*.txt )
array_length=${#myarray[@]}

# Not found if the first element of the array is the unexpanded string
# (ie, if it contains a "*")
if [[ ${myarray[0]} =~ [*] ]] ; then
   echo "No files not found"
elif [ $array_length -eq 1 ] ; then
   echo "File was found"
else
   echo "Files were found"
fi

for myfile in ${myarray[@]}
do
  echo "$myfile"
done

Yes, this does smell like Perl. I am glad I didn't step in it ;)

Peter Mortensen
  • 30,738
  • 21
  • 105
  • 131
Ben Slade
  • 478
  • 5
  • 11
1

IMHO it's better to use find always when testing for files, globs or directories. The stumbling block in doing so is find's exit status: 0 if all paths were traversed successfully, >0 otherwise. The expression you passed to find creates no echo in its exit code.

The following example tests if a directory has entries:

$ mkdir A
$ touch A/b
$ find A -maxdepth 0 -not -empty -print | head -n1 | grep -q . && echo 'not empty'
not empty

When A has no files grep fails:

$ rm A/b
$ find A -maxdepth 0 -not -empty -print | head -n1 | grep -q . || echo 'empty'
empty

When A does not exist grep fails again because find only prints to stderr:

$ rmdir A
$ find A -maxdepth 0 -not -empty -print | head -n1 | grep -q . && echo 'not empty' || echo 'empty'
find: 'A': No such file or directory
empty

Replace -not -empty by any other find expression, but be careful if you -exec a command that prints to stdout. You may want to grep for a more specific expression in such cases.

This approach works nicely in shell scripts. The originally question was to look for the glob xorg-x11-fonts*:

if find -maxdepth 0 -name 'xorg-x11-fonts*' -print | head -n1 | grep -q .
then
    : the glob matched
else
    : ...not
fi

Note that the else-branched is reached if xorg-x11-fonts* had not matched, or find encountered an error. To distinguish the case use $?.

Andreas Spindler
  • 7,568
  • 4
  • 43
  • 34
  • 1
    You probably meant -maxdepth 1 when using -name, since -maxdepth 0 will look at the current directory and not its contents. – Chris Cogdon Jul 29 '16 at 23:40
0

If there is a huge amount of files on a network folder using the wildcard is questionable (speed, or command line arguments overflow).

I ended up with:

if [ -n "$(find somedir/that_may_not_exist_yet -maxdepth 1 -name \*.ext -print -quit)" ] ; then
  echo Such file exists
fi
luxigo
  • 123
  • 1
  • 5
0
if [ `ls path1/* path2/* 2> /dev/null | wc -l` -ne 0 ]; then echo ok; else echo no; fi
Dan Elias
  • 9
  • 1
  • 1
    This looks like a grab bag of "don't do that" shell antipatterns. Don't use `ls` in scripts, don't check if the word count is zero, watch out for pretzel logic with backticks. – tripleee Jul 31 '20 at 07:22
  • An explanation would be in order. E.g., what is the idea/gist? Please respond by [editing (changing) your answer](https://stackoverflow.com/posts/46518997/edit), not here in comments (***without*** "Edit:", "Update:", or similar - the answer should appear as if it was written today). – Peter Mortensen Nov 03 '21 at 01:08
0

Try this

fileTarget="xorg-x11-fonts*"

filesFound=$(ls $fileTarget)

case ${filesFound} in
  "" ) printf "NO files found for target=${fileTarget}\n" ;;
   * ) printf "FileTarget Files found=${filesFound}\n" ;;
esac

Test

fileTarget="*.html"  # Where I have some HTML documents in the current directory

FileTarget Files found=Baby21.html
baby22.html
charlie  22.html
charlie21.html
charlie22.html
charlie23.html

fileTarget="xorg-x11-fonts*"

NO files found for target=xorg-x11-fonts*

Note that this only works in the current directory, or where the variable fileTarget includes the path you want to inspect.

Peter Mortensen
  • 30,738
  • 21
  • 105
  • 131
shellter
  • 36,525
  • 7
  • 83
  • 90
  • Your code will fail if `fileTarget` contains whitespace (e.g., `fileTarget="my file*"`). – Richard Hansen Jun 17 '11 at 06:34
  • @RichardHansen what the solution when there is whitespace? – Ross Mar 28 '14 at 22:57
  • @Ross: Use the accepted answer: `if ls "my file"* >/dev/null 2>&1; then ...` – Richard Hansen Mar 29 '14 at 02:59
  • @RichardHansen thanks, sorry – not working for me. Have it fixed now . – Ross Apr 02 '14 at 09:44
  • 1
    @Ross, I've added an edit to mine that should work with files with spaces. Basically `case "${filesFound}" in ....` . Good luck to all. – shellter Apr 02 '14 at 11:23
  • According to the [POSIX spec for `case`](http://pubs.opengroup.org/onlinepubs/9699919799/utilities/V3_chap02.html#tag_18_09_04_05), the word after `case` isn't subject to field splitting or pathname expansion so the double quotes you added have no effect. The problem is with the field splitting in `ls $fileTarget`. – Richard Hansen Apr 02 '14 at 23:52
  • @Ross, RichardHansen is onto something, the dbl-quotes don't really matter, maybe that's why I didn't have them in the first place. It's so long ago now I'm not sure. I went back to my test dir for this question, and made a link as `charlie 22.html`, I've edited results above. Will this handle every case as well as `find ... -print0 | xargs -0 ..`?, probably not. Does it work in environment where you control what filenames are created? It does for me, and I mean that I use this construct regularly (in an environment where I do control the filenames that are created ;-) ). Good luck to all. – shellter Apr 03 '14 at 03:27
-1

Use:

if ls -l  | grep -q 'xorg-x11-fonts.*' # grep needs a regex, not a shell glob
then
     # do something
else
     # do something else
fi
Peter Mortensen
  • 30,738
  • 21
  • 105
  • 131
Ankur Agarwal
  • 23,692
  • 41
  • 137
  • 208
  • 3
    No, [don't use `ls` in scripts](http://mywiki.wooledge.org/ParsingLs) and the `.*` wildcard is redundant (you probably meant `grep -q '^xorg-x1-fonts'`). – tripleee Sep 26 '17 at 09:08
  • [why not parse `ls`](https://unix.stackexchange.com/q/128985/44425) – phuclv May 31 '18 at 08:48
  • While this code may answer the question, providing additional context regarding *why* and/or *how* this code answers the question improves its long-term value. – PCM Nov 03 '21 at 03:35
-1

You can also cut other files out

if [ -e $( echo $1 | cut -d" " -f1 ) ] ; then
   ...
fi
Giacomo1968
  • 25,759
  • 11
  • 71
  • 103
McCloud
  • 1
  • 2
-16

man test.

if [ -e file ]; then
...
fi

will work for directory and file.

Peter Mortensen
  • 30,738
  • 21
  • 105
  • 131