Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Bash asterisk omits files that start with '.'? [duplicate]

I'm using a bash script to iterate over all files in a directory. But the loop is skipping over files that begin with a '.' such as '.bashrc' I'm not sure if .bashrc is failing the file test or is being omitted from the wildcard '*'. I've tried double quotes around "$item" but same result. How can I make this loop include .bashrc files?

id=0     
cd $USERDIR
for item in *
do
    if [[ -f $item ]]; then
        cdir[$id]=$item
        id=$(($id+1))
        echo $item
    fi
done  
like image 385
jott19 Avatar asked Jan 03 '14 02:01

jott19


People also ask

What does an asterisk in a file glob match?

An asterisk is replaced by any number of characters in a filename. For example, ae* would match aegis, aerie, aeon, etc. if those files were in the same directory. You can use this to save typing for a single filename (for example, al* for alphabet. txt) or to name many files at once (as in ae*).

What is asterisk in bash?

The * is a wildcard in Bash, it means "all files in the current directory". If you want to pass an asterisk as an argument to your program, you do it the same way you do it with every other program: you escape it with a backslash or quote it.

How do you check if a pattern exists in a file in Unix?

Syntax. grep -q [PATTERN] [FILE] && echo $? The exit status is 0 (true) if the pattern was found; The exit status is 1 (false) if the pattern was not found.

How do you check if a file exists in a directory in Linux?

In Linux everything is a file. You can use the test command followed by the operator -f to test if a file exists and if it's a regular file. In the same way the test command followed by the operator -d allows to test if a file exists and if it's a directory.


2 Answers

It's not the loop omitting those files, it's the expansion of * by the shell. If you want the dotfiles as well, use:

for item in .* *

From the bash manpage:

When a pattern is used for pathname expansion, the character "." at the start of a name or immediately following a slash must be matched explicitly, unless the shell option dotglob is set.

That last sentence on the dotglob option may seem to be useful but you should be wary of changing options that may affect later code. The safest way to use them is to ensure you set them back to their original values, something like:

rest_cmd=$(shopt -p dotglob)  # Get restoration command
shopt -s dotglob              # Set option
for item in * ; do
    blah blah blah
done
${rest_cmd}                   # Restore option

But, in this case, I'd just stick with the explicit use of .* * since that's an easy solution.

like image 138
paxdiablo Avatar answered Sep 19 '22 22:09

paxdiablo


You can set dotglob

shopt -s dotglob
for item in *; do echo "$item"; done
like image 34
ray Avatar answered Sep 20 '22 22:09

ray