Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Check if a file exists with a wildcard in a shell script [duplicate]

Tags:

shell

sh

wildcard

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.

like image 360
Danny Avatar asked Jun 15 '11 19:06

Danny


People also ask

What is $@ in bash script?

bash [filename] runs the commands saved in a file. $@ refers to all of a shell script's command-line arguments. $1 , $2 , etc., refer to the first command-line argument, the second command-line argument, etc. Place variables in quotes if the values might have spaces in them.

What is wildcards in shell script?

A wildcard is a character that can be used as a substitute for any of a class of characters in a search, thereby greatly increasing the flexibility and efficiency of searches. Wildcards are commonly used in shell commands in Linux and other Unix-like operating systems.

How do I check if a file exists in Linux?

Check if File Exists When checking if a file exists, the most commonly used FILE operators are -e and -f . The first one will check whether a file exists regardless of the type, while the second one will return true only if the FILE is a regular file (not a directory or a device).

Do commands interpret wildcards?

You can use them with any command such as ls command or rm command to list or remove files matching a given criteria, receptively. These wildcards are interpreted by the shell and the results are returned to the command you run.


2 Answers

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.

like image 98
Costi Ciudatu Avatar answered Oct 17 '22 02:10

Costi Ciudatu


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.

like image 34
flabdablet Avatar answered Oct 17 '22 01:10

flabdablet