Bash for loop with wildcards and hidden files
FILES=".bash*"
works because the hidden files name begin with a .
FILES="bash*"
doesn't work because the hidden files name begin with a .
not a b
FILES="*bash*"
doesn't work because the *
wildcard at the beginning of a string omits hidden files.
Bash loop through directory including hidden file
As chepner noted in the comments below, this solution assumes you're running GNU bash
along with GNU find
GNU sort
...
GNU find
can be prevented from recursing into subdirectories with the -maxdepth
option. Then use -print0
to end every filename with a 0x00
byte instead of the newline you'd usually get from -print
.
The sort -z
sorts the filenames between the 0x00
bytes.
Then, you can use sed
to get rid of the dot and dot-dot directory entries (although GNU find
seems to exclude the ..
already).
I also used sed
to get read of the ./
in front of every filename. basename
could do that too, but older systems didn't have basename
, and you might not trust it to handle the funky characters right.
(These sed
commands each required two cases: one for a pattern at the start of the string, and one for the pattern between 0x00
bytes. These were so ugly I split them out into separate functions.)
The read
command doesn't have a -z
or -0
option like some commands, but you can fake it with -d ""
and blanking the IFS
environment variable.
The additional -r
option prevents a backslash-newline combo from being interpreted as a line continuation. (A file called backslash\\nnewline
would otherwise be mangled to backslashnewline
.) It might be worth seeing if other backslash-combos get interpreted as escape sequences.
remove_dot_and_dotdot_dirs()
{
sed \
-e 's/^[.]\{1,2\}\x00//' \
-e 's/\x00[.]\{1,2\}\x00/\x00/g'
}
remove_leading_dotslash()
{
sed \
-e 's/^[.]\///' \
-e 's/\x00[.]\//\x00/g'
}
IFS=""
find . -maxdepth 1 -print0 |
sort -z |
remove_dot_and_dotdot_dirs |
remove_leading_dotslash |
while read -r -d "" filename
do
echo "Doing something with file '${filename}'..."
done
How to loop through a directory that includes files and hidden files
You can use the find
command to achieved this as per this other answer: Delete files older than specific file
inputfile=$1
direct=$2
find $direct/ -type f ! -newer $inputfile
Bash: Whats the correct way to loop through a directory and sub-directories including hidden files?
Do:
for f in * .[!.]*; do
I think it should work on any posix compatible shell. The documentation can be found in posix Shell Command Language 2.13 Pattern Matching Notation. The .
matches a dot, then [!.]
is a pattern bracked expression that matches everything but a dot, so it effectively excludes .
current directory and ..
parent directory from the match.
Notes:
- Great script, good coding, keep it up!
- Quote your variables expansions, especially if they are filenames. Don't
get_file_size $f
, doget_file_size "$f"
. When to wrap quotes aroung a shell variable? - Don't use backticks `, they're use is discouraged. Use
$(...)
everywhere instead. Obsolete and deprecated syntax bash hackers wiki. - Don't use
function name()
, is a mix of two shell notations. Justname() { .. }
to define a function, which is posix compatible and will work everywhere. - Just
get_file_size() { stat --printf="%s" "$1"; }
. No need for variable andecho
. - The
[[
is a bash extension. So oncsh
use[
. Remember to quote your variable expansions. - I think I would
find . -type f -printf "%s\n" | awk '{ sum+=$1 } END{print sum}'
Loop through a directory and perform action on files with specific permissions in unix
The exit status of grep
indicates whether the input matched the pattern. So you can use it as the condition in if
.
if ls -ld "$FILE" | grep -q -F 'drwx-----T+'; then
# do what you want
fi
The -q
option prevents grep
from printing the match, and -F
makes it match a fixed string rather than treating it as a regular expression (+
has special meaning in regexp).
Iterate all files in a directory (including files that start with '.' - hidden files) in linux/android
IFS=$'\n'; for f in $(ls -a);do echo "$f"; done
How to loop over directories in Linux?
cd /tmp
find . -maxdepth 1 -mindepth 1 -type d -printf '%f\n'
A short explanation:
find
finds files (quite obviously).
is the current directory, which after thecd
is/tmp
(IMHO this is more flexible than having/tmp
directly in thefind
command. You have only one place, thecd
, to change, if you want more actions to take place in this folder)-maxdepth 1
and-mindepth 1
make sure thatfind
only looks in the current directory and doesn't include.
itself in the result-type d
looks only for directories-printf '%f\n
prints only the found folder's name (plus a newline) for each hit.
Et voilà!
How to loop through a directory recursively to delete files with certain extensions
find
is just made for that.
find /tmp -name '*.pdf' -or -name '*.doc' | xargs rm
Recursively loop through files in bash and manipulate each file through a command
Use globstar
:
shopt -s globstar
for f in ./**; do
touch "$f"
done
From the Bash manual:
globstar
If set, the pattern ‘
**
’ used in a filename expansion context will match all files and zero or more directories and subdirectories. If the pattern is followed by a ‘/
’, only directories and subdirectories match.
BTW, always quote your variables, and use ./
in case of filenames that look like options.
This is based on codeforester's answer here
Related Topics
Vs Code Ssh Remote Connection Issues
Find Which Program Caused a Core Dump File
Finding The Max and Min Values and Printing The Line from a File
Os X Permission Denied for /Usr/Local/Lib
Implementing Basic File System
Fork() and Stdout/Stderr to The Console from Child Processes
Angular Cli App Not Running When Deploying to Linux App Service
Difference Between a Stripped Binary and a Non Stripped Binary in Linux
Unknown Symbol in While Loading a Kernel Module
Mongo Daemon Doesn't Run by Service Mongod Start
Copy Lines Containing Word from One File to Another File in Linux
How to Get Command History by Cursor Key in Linux Tclsh
Bash Arrays and Negative Subscripts, Yes or No
Is There a 'ssh-Add' Linux Alpine One Liner
Capture Stdin/Stderr/Stdout of a Process After It's Been Started, Using Command Line
How to Convert Dynamically Linked Application to Statically One