Iterate over a list of files with spaces
You could replace the word-based iteration with a line-based one:
find . -iname "foo*" | while read f
do
# ... loop body
done
Loop through Filenames with spaces Bash using variables
Looks to me like the whole loop ought to be mkdir -p "$File_Directory"
...
But assuming he meant to put them all in the same dir:
$: File_Directory=a/b/c/d/e/f/g
$: ( IFS=/; for d in $File_Directory; do mkdir -p "$d"; done; )
That does play a little fast and loose with the parameter parsing though.
for loop through files with spaces in their names
Use the -Z1
option of unzip
instead of -l
. It outputs one file per line with no additional information. You should read its output instead of loop over it with for to prevent word splitting. You might still have problems with filenames containing a newline (but I wasn't able to zip them, $'a\nb'
was stored as a^Jb
and extracted as ab
).
Also, your if
is missing a then
.
Also, don't parse the output of ls
, you can iterate over the globbed file mask itself.
You don't need to check that grep
outputs anything, just run it with -q
and check its exit status.
Don't forget to doublequote variables that might contain whitespace or other special characters.
for z in /path/to/archives/*.zip ; do
while IFS= read -r f ; do
if unzip -p "$z" "$f" | grep -q "$string" ; then
unzip "$z" "$f"
fi
done < <(unzip -Z1 "$z" '*.xml')
done
How to iterate through all files in a directory, ordered by date created, with some filenames have spaces in their names
Use find
in combination with xargs
to pass file names with NUL-byte separation, and use a while
read loop for efficiency and space preservation:
find /path/to/dir -type f -print0 | xargs -0 ls -t | while read file
do
ls "$file" # or whatever you want with $file, which may have spaces
# so always enclose it in double quotes
done
find
generates the list of files, ls
arranges them, by time in this case. To reverse the sort order, replace -t
with -tr
. If you wanted to sort by size, replace -t
with -s
.
Example:
$ touch -d '2015-06-17' 'foo foo'
$ touch -d '2016-02-12' 'bar bar'
$ touch -d '2016-05-01' 'baz baz'
$ ls -1
bar bar
baz baz
foo foo
$ find . -type f -print0 | xargs -0 ls -t | while read file
> do
> ls -l "$file"
> done
-rw-rw-r-- 1 bishop bishop 0 May 1 00:00 ./baz baz
-rw-rw-r-- 1 bishop bishop 0 Feb 12 00:00 ./bar bar
-rw-rw-r-- 1 bishop bishop 0 Jun 17 2015 ./foo foo
For completeness, I'll highlight a point from comments to the question: -t
is sorting by modification time, which not strictly creation time. The file system on which these files reside dictates whether or not creation time is available. Since your initial attempts used -t
, I figured modification time was what you were concerned about, even if it's not pedantically true.
If you want creation time, you'll have to pull it from some source, like stat
or the file name if its encoded there. This basically means replacing the xargs -0 ls -t
with a suitable command piped to sort
, something like: xargs -0 stat -c '%W' | sort -n
bash iterate over a directory sorted by file size
You can use a mix of find
(to print file sizes and names), sort
(to sort the output of find
) and cut
(to remove the sizes). In case you have very unusual file names containing any possible character including newlines, it is safer to separate the files by a character that cannot be part of a name: NUL
.
#/bin/bash
if [ -z "$1" ]; then
echo "Please supply the filename suffixes to delete.";
exit;
fi;
filter=$1;
while IFS= read -r -d '' -u 3 FILE; do
clear
cat "$FILE"
printf '\n\n'
rm -i "$FILE"
done 3< <(find . -mindepth 1 -maxdepth 1 -type f -name "*.$filter" \
-printf '%s\t%p\0' | sort -zn | cut -zf 2-)
Note that we must use a different file descriptor than stdin
(3
in this example) to pass the file names to the loop. Else, if we use stdin
, it will also be used to provide the answers to rm -i
.
Cant loop over files with spaces in the filename, windows batch file and image magick
To handle filenames with spaces, quote them. For example your command
convert %%a -sampling-factor 4:2:0 -strip -quality 85 -interlace JPEG -colorspace RGB -resize %%f %%f\%%a
should change to
convert "%%a" -sampling-factor 4:2:0 -strip -quality 85 -interlace JPEG -colorspace RGB -resize "%%f" "%%f\%%a"
same with the mogrify
command:
mogrify -format webp "%%f\%%a"
The quotes doesn't do any harm, when there is no space, so as best practice get used to always qoute path- or file names.
Related Topics
32-Bit Absolute Addresses No Longer Allowed in X86-64 Linux
How to Prevent a Background Process from Being Stopped After Closing Ssh Client in Linux
How to Get Overall Cpu Usage (E.G. 57%) on Linux
How to Parse Xml Using Shellscript
How to Permanently Export a Variable in Linux
How to Setup Public-Key Authentication
Run an Untrusted C Program in a Sandbox in Linux That Prevents It from Opening Files, Forking, etc.
My Shell Script Stops After Exec
Recursively Counting Files in a Linux Directory
Determine Direct Shared Object Dependencies of a Linux Binary
Multiple Glibc Libraries on a Single Host
How Do the Likely/Unlikely Macros in the Linux Kernel Work and What Is Their Benefit
How to Link to a Specific Glibc Version
Better Way to Rename Files Based on Multiple Patterns
Sorting Multiple Keys With Unix Sort
Maximum Number of Processes in Linux
How to Normalize a File Path in Bash
Minimal Executable Size Now 10X Larger After Linking Than 2 Years Ago, For Tiny Programs