ZSH — Loop files, ignore certain patterns (no ls or find)

The name of the pictureThe name of the pictureThe name of the pictureClash Royale CLAN TAG#URR8PPP












1















I just finished reading an article titled "Why you shouldn't parse the output of ls". I want to loop each file in a directory, and the article states that the following is one of the most basic and ideal ways.



for f in *; do
echo $f
# …do stuff
done


The one thing I do not understand is how can I ignore certain files and directories? I use ZSH and have turned extendedglob on. Because of this, I thought this would be viable: for f in *^.jpg; do…, but it only echoes "*^.jpg", no files.



How can I keep the loop mostly as is, but incorporate the ability to exclude certain patterns? Bonus question: can you make the glob recursive?










share|improve this question
























  • Have you actually enabled that option in the script that you are running? It would not be enough to enable it in the interactive shell that you use to launch the script from.

    – Kusalananda
    Mar 6 at 13:13












  • Also, are you actually running the script with zsh? Ordinarily, the zsh shell would complain when no names matches the pattern.

    – Kusalananda
    Mar 6 at 13:37











  • Placing setopt extendedglob inside does give the error "setopt: command not found", hmm. My script begins with #!/bin/zsh, so I would guess it runs w/ zsh, yes.

    – Audun Olsen
    Mar 6 at 13:44











  • I seem to have done the error of calling the script prefaced with sh not zsh. Is it conventional to call scripts with zsh filename.sh?

    – Audun Olsen
    Mar 6 at 13:54











  • It is conventional to call a scripts with the correct interpreter. A Perl script with perl, a zsh script with zsh, a bash script with bash, etc. It is also conventional to make script executable and add a proper #!-line at the top pointing to the correct interpreter so that you can just use ./filename.sh.

    – Kusalananda
    Mar 6 at 13:56
















1















I just finished reading an article titled "Why you shouldn't parse the output of ls". I want to loop each file in a directory, and the article states that the following is one of the most basic and ideal ways.



for f in *; do
echo $f
# …do stuff
done


The one thing I do not understand is how can I ignore certain files and directories? I use ZSH and have turned extendedglob on. Because of this, I thought this would be viable: for f in *^.jpg; do…, but it only echoes "*^.jpg", no files.



How can I keep the loop mostly as is, but incorporate the ability to exclude certain patterns? Bonus question: can you make the glob recursive?










share|improve this question
























  • Have you actually enabled that option in the script that you are running? It would not be enough to enable it in the interactive shell that you use to launch the script from.

    – Kusalananda
    Mar 6 at 13:13












  • Also, are you actually running the script with zsh? Ordinarily, the zsh shell would complain when no names matches the pattern.

    – Kusalananda
    Mar 6 at 13:37











  • Placing setopt extendedglob inside does give the error "setopt: command not found", hmm. My script begins with #!/bin/zsh, so I would guess it runs w/ zsh, yes.

    – Audun Olsen
    Mar 6 at 13:44











  • I seem to have done the error of calling the script prefaced with sh not zsh. Is it conventional to call scripts with zsh filename.sh?

    – Audun Olsen
    Mar 6 at 13:54











  • It is conventional to call a scripts with the correct interpreter. A Perl script with perl, a zsh script with zsh, a bash script with bash, etc. It is also conventional to make script executable and add a proper #!-line at the top pointing to the correct interpreter so that you can just use ./filename.sh.

    – Kusalananda
    Mar 6 at 13:56














1












1








1








I just finished reading an article titled "Why you shouldn't parse the output of ls". I want to loop each file in a directory, and the article states that the following is one of the most basic and ideal ways.



for f in *; do
echo $f
# …do stuff
done


The one thing I do not understand is how can I ignore certain files and directories? I use ZSH and have turned extendedglob on. Because of this, I thought this would be viable: for f in *^.jpg; do…, but it only echoes "*^.jpg", no files.



How can I keep the loop mostly as is, but incorporate the ability to exclude certain patterns? Bonus question: can you make the glob recursive?










share|improve this question
















I just finished reading an article titled "Why you shouldn't parse the output of ls". I want to loop each file in a directory, and the article states that the following is one of the most basic and ideal ways.



for f in *; do
echo $f
# …do stuff
done


The one thing I do not understand is how can I ignore certain files and directories? I use ZSH and have turned extendedglob on. Because of this, I thought this would be viable: for f in *^.jpg; do…, but it only echoes "*^.jpg", no files.



How can I keep the loop mostly as is, but incorporate the ability to exclude certain patterns? Bonus question: can you make the glob recursive?







zsh wildcards






share|improve this question















share|improve this question













share|improve this question




share|improve this question








edited Mar 6 at 13:13









Rui F Ribeiro

41.9k1483142




41.9k1483142










asked Mar 6 at 13:11









Audun OlsenAudun Olsen

133




133












  • Have you actually enabled that option in the script that you are running? It would not be enough to enable it in the interactive shell that you use to launch the script from.

    – Kusalananda
    Mar 6 at 13:13












  • Also, are you actually running the script with zsh? Ordinarily, the zsh shell would complain when no names matches the pattern.

    – Kusalananda
    Mar 6 at 13:37











  • Placing setopt extendedglob inside does give the error "setopt: command not found", hmm. My script begins with #!/bin/zsh, so I would guess it runs w/ zsh, yes.

    – Audun Olsen
    Mar 6 at 13:44











  • I seem to have done the error of calling the script prefaced with sh not zsh. Is it conventional to call scripts with zsh filename.sh?

    – Audun Olsen
    Mar 6 at 13:54











  • It is conventional to call a scripts with the correct interpreter. A Perl script with perl, a zsh script with zsh, a bash script with bash, etc. It is also conventional to make script executable and add a proper #!-line at the top pointing to the correct interpreter so that you can just use ./filename.sh.

    – Kusalananda
    Mar 6 at 13:56


















  • Have you actually enabled that option in the script that you are running? It would not be enough to enable it in the interactive shell that you use to launch the script from.

    – Kusalananda
    Mar 6 at 13:13












  • Also, are you actually running the script with zsh? Ordinarily, the zsh shell would complain when no names matches the pattern.

    – Kusalananda
    Mar 6 at 13:37











  • Placing setopt extendedglob inside does give the error "setopt: command not found", hmm. My script begins with #!/bin/zsh, so I would guess it runs w/ zsh, yes.

    – Audun Olsen
    Mar 6 at 13:44











  • I seem to have done the error of calling the script prefaced with sh not zsh. Is it conventional to call scripts with zsh filename.sh?

    – Audun Olsen
    Mar 6 at 13:54











  • It is conventional to call a scripts with the correct interpreter. A Perl script with perl, a zsh script with zsh, a bash script with bash, etc. It is also conventional to make script executable and add a proper #!-line at the top pointing to the correct interpreter so that you can just use ./filename.sh.

    – Kusalananda
    Mar 6 at 13:56

















Have you actually enabled that option in the script that you are running? It would not be enough to enable it in the interactive shell that you use to launch the script from.

– Kusalananda
Mar 6 at 13:13






Have you actually enabled that option in the script that you are running? It would not be enough to enable it in the interactive shell that you use to launch the script from.

– Kusalananda
Mar 6 at 13:13














Also, are you actually running the script with zsh? Ordinarily, the zsh shell would complain when no names matches the pattern.

– Kusalananda
Mar 6 at 13:37





Also, are you actually running the script with zsh? Ordinarily, the zsh shell would complain when no names matches the pattern.

– Kusalananda
Mar 6 at 13:37













Placing setopt extendedglob inside does give the error "setopt: command not found", hmm. My script begins with #!/bin/zsh, so I would guess it runs w/ zsh, yes.

– Audun Olsen
Mar 6 at 13:44





Placing setopt extendedglob inside does give the error "setopt: command not found", hmm. My script begins with #!/bin/zsh, so I would guess it runs w/ zsh, yes.

– Audun Olsen
Mar 6 at 13:44













I seem to have done the error of calling the script prefaced with sh not zsh. Is it conventional to call scripts with zsh filename.sh?

– Audun Olsen
Mar 6 at 13:54





I seem to have done the error of calling the script prefaced with sh not zsh. Is it conventional to call scripts with zsh filename.sh?

– Audun Olsen
Mar 6 at 13:54













It is conventional to call a scripts with the correct interpreter. A Perl script with perl, a zsh script with zsh, a bash script with bash, etc. It is also conventional to make script executable and add a proper #!-line at the top pointing to the correct interpreter so that you can just use ./filename.sh.

– Kusalananda
Mar 6 at 13:56






It is conventional to call a scripts with the correct interpreter. A Perl script with perl, a zsh script with zsh, a bash script with bash, etc. It is also conventional to make script executable and add a proper #!-line at the top pointing to the correct interpreter so that you can just use ./filename.sh.

– Kusalananda
Mar 6 at 13:56











1 Answer
1






active

oldest

votes


















4














Zsh provides very nice ways to enumerate files. They're documented in the manual under “Filename Generation”, but the zsh manual isn't very easy to follow.



By default, if there are no matching files, you'll get an error, which is often desirable on the command line, but not in scripts. To disable this error, either put this near the beginning of your script to turn on the null_glob option:



setopt null_glob

for x in *; do …


or use the N glob qualifier:



# Reliably iterate over non-dot files
for x in *(N); do …


Either snippet above iterates over all the files in the current directory that are not dot files. If there is no such file, the loop doesn't run at all (unlike sh where the loop body unhelpfully runs once on the unexpanded glob *, and default zsh where the glob causes an error).



To include dot files in the iteration, either turn on the got_glob option or use the D glob qualifier.



# Reliably iterate over all files in the current directory
for x in *(DN); do …


I recommend the glob qualifier method, even if it's more verbose, because it will keep behaving the same way even if you copy-paste that snippet to a script that didn't turn on the same options.



To exclude certain files based on their name, you can use the glob operators ^ and ~. Note that these require setopt extended_glob in your script² (this is not inherited from your runtime environment or your .zshrc¹). For example, to exclude *.jpg files, either write *~*.jpg or ^*.jpg.



(Note that what you wrote, *^.jpg, would by default cause an error in zsh. If you're seeing *^.jpg printed out, then either you're running zsh with nomatch turned off (it's on by default), which is normally only done when emulating sh or ksh, or else you're actually running that script under an sh shell, probably because it's missing a shebang line at the top.)



setopt extended_glob
# Iterate over all the files in the current directory except *.jpg and .*
for x in *~*.jpg(N); do …


If you want to traverse subdirectories recursively, it's easy: just use **/.



setopt extended_glob
# Iterate over all the files in the current directory and its (grand-)*children except *.jpg and .*
for x in **/*~*.jpg(N); do …


Through glob qualifiers, you can also select files based on conditions other than their name. For example, to loop over regular files only, excluding directories, symbolic links, etc.:



# Iterate over all regular files in the current directory and its (grand-)*children except *.jpg and .*
for x in **/*(.DN); do …


You can even run arbitrary code to decide whether to include a file or not with the e or + glob qualifier. However, when the wildcard pattern is used in a for loop, it's clearer to put the filtering code at the top of the loop body.



¹ You could put setopt extended_glob in ~/.zshenv, but I strongly recommend against using .zshenv, because any script that makes assumptions about what's in there would break on a different machine or a different account.

² If you're writing a zsh completion function, these run in an environment where extended_glob is turned on.






share|improve this answer

























  • *^.jpg would expand to all the files whose name ends in ^.jpg without extendedglob and all files with extentedglob, even file.jpg as that's for instance the empty string (matched by *) followed by file.jpg (matched by ^.jpg as that's not .jpg) (or file.jpg followed by the empty string, or file.jp followed by g, etc.).

    – Stéphane Chazelas
    Mar 8 at 9:40












Your Answer








StackExchange.ready(function()
var channelOptions =
tags: "".split(" "),
id: "106"
;
initTagRenderer("".split(" "), "".split(" "), channelOptions);

StackExchange.using("externalEditor", function()
// Have to fire editor after snippets, if snippets enabled
if (StackExchange.settings.snippets.snippetsEnabled)
StackExchange.using("snippets", function()
createEditor();
);

else
createEditor();

);

function createEditor()
StackExchange.prepareEditor(
heartbeatType: 'answer',
autoActivateHeartbeat: false,
convertImagesToLinks: false,
noModals: true,
showLowRepImageUploadWarning: true,
reputationToPostImages: null,
bindNavPrevention: true,
postfix: "",
imageUploader:
brandingHtml: "Powered by u003ca class="icon-imgur-white" href="https://imgur.com/"u003eu003c/au003e",
contentPolicyHtml: "User contributions licensed under u003ca href="https://creativecommons.org/licenses/by-sa/3.0/"u003ecc by-sa 3.0 with attribution requiredu003c/au003e u003ca href="https://stackoverflow.com/legal/content-policy"u003e(content policy)u003c/au003e",
allowUrls: true
,
onDemand: true,
discardSelector: ".discard-answer"
,immediatelyShowMarkdownHelp:true
);



);













draft saved

draft discarded


















StackExchange.ready(
function ()
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2funix.stackexchange.com%2fquestions%2f504704%2fzsh-loop-files-ignore-certain-patterns-no-ls-or-find%23new-answer', 'question_page');

);

Post as a guest















Required, but never shown

























1 Answer
1






active

oldest

votes








1 Answer
1






active

oldest

votes









active

oldest

votes






active

oldest

votes









4














Zsh provides very nice ways to enumerate files. They're documented in the manual under “Filename Generation”, but the zsh manual isn't very easy to follow.



By default, if there are no matching files, you'll get an error, which is often desirable on the command line, but not in scripts. To disable this error, either put this near the beginning of your script to turn on the null_glob option:



setopt null_glob

for x in *; do …


or use the N glob qualifier:



# Reliably iterate over non-dot files
for x in *(N); do …


Either snippet above iterates over all the files in the current directory that are not dot files. If there is no such file, the loop doesn't run at all (unlike sh where the loop body unhelpfully runs once on the unexpanded glob *, and default zsh where the glob causes an error).



To include dot files in the iteration, either turn on the got_glob option or use the D glob qualifier.



# Reliably iterate over all files in the current directory
for x in *(DN); do …


I recommend the glob qualifier method, even if it's more verbose, because it will keep behaving the same way even if you copy-paste that snippet to a script that didn't turn on the same options.



To exclude certain files based on their name, you can use the glob operators ^ and ~. Note that these require setopt extended_glob in your script² (this is not inherited from your runtime environment or your .zshrc¹). For example, to exclude *.jpg files, either write *~*.jpg or ^*.jpg.



(Note that what you wrote, *^.jpg, would by default cause an error in zsh. If you're seeing *^.jpg printed out, then either you're running zsh with nomatch turned off (it's on by default), which is normally only done when emulating sh or ksh, or else you're actually running that script under an sh shell, probably because it's missing a shebang line at the top.)



setopt extended_glob
# Iterate over all the files in the current directory except *.jpg and .*
for x in *~*.jpg(N); do …


If you want to traverse subdirectories recursively, it's easy: just use **/.



setopt extended_glob
# Iterate over all the files in the current directory and its (grand-)*children except *.jpg and .*
for x in **/*~*.jpg(N); do …


Through glob qualifiers, you can also select files based on conditions other than their name. For example, to loop over regular files only, excluding directories, symbolic links, etc.:



# Iterate over all regular files in the current directory and its (grand-)*children except *.jpg and .*
for x in **/*(.DN); do …


You can even run arbitrary code to decide whether to include a file or not with the e or + glob qualifier. However, when the wildcard pattern is used in a for loop, it's clearer to put the filtering code at the top of the loop body.



¹ You could put setopt extended_glob in ~/.zshenv, but I strongly recommend against using .zshenv, because any script that makes assumptions about what's in there would break on a different machine or a different account.

² If you're writing a zsh completion function, these run in an environment where extended_glob is turned on.






share|improve this answer

























  • *^.jpg would expand to all the files whose name ends in ^.jpg without extendedglob and all files with extentedglob, even file.jpg as that's for instance the empty string (matched by *) followed by file.jpg (matched by ^.jpg as that's not .jpg) (or file.jpg followed by the empty string, or file.jp followed by g, etc.).

    – Stéphane Chazelas
    Mar 8 at 9:40
















4














Zsh provides very nice ways to enumerate files. They're documented in the manual under “Filename Generation”, but the zsh manual isn't very easy to follow.



By default, if there are no matching files, you'll get an error, which is often desirable on the command line, but not in scripts. To disable this error, either put this near the beginning of your script to turn on the null_glob option:



setopt null_glob

for x in *; do …


or use the N glob qualifier:



# Reliably iterate over non-dot files
for x in *(N); do …


Either snippet above iterates over all the files in the current directory that are not dot files. If there is no such file, the loop doesn't run at all (unlike sh where the loop body unhelpfully runs once on the unexpanded glob *, and default zsh where the glob causes an error).



To include dot files in the iteration, either turn on the got_glob option or use the D glob qualifier.



# Reliably iterate over all files in the current directory
for x in *(DN); do …


I recommend the glob qualifier method, even if it's more verbose, because it will keep behaving the same way even if you copy-paste that snippet to a script that didn't turn on the same options.



To exclude certain files based on their name, you can use the glob operators ^ and ~. Note that these require setopt extended_glob in your script² (this is not inherited from your runtime environment or your .zshrc¹). For example, to exclude *.jpg files, either write *~*.jpg or ^*.jpg.



(Note that what you wrote, *^.jpg, would by default cause an error in zsh. If you're seeing *^.jpg printed out, then either you're running zsh with nomatch turned off (it's on by default), which is normally only done when emulating sh or ksh, or else you're actually running that script under an sh shell, probably because it's missing a shebang line at the top.)



setopt extended_glob
# Iterate over all the files in the current directory except *.jpg and .*
for x in *~*.jpg(N); do …


If you want to traverse subdirectories recursively, it's easy: just use **/.



setopt extended_glob
# Iterate over all the files in the current directory and its (grand-)*children except *.jpg and .*
for x in **/*~*.jpg(N); do …


Through glob qualifiers, you can also select files based on conditions other than their name. For example, to loop over regular files only, excluding directories, symbolic links, etc.:



# Iterate over all regular files in the current directory and its (grand-)*children except *.jpg and .*
for x in **/*(.DN); do …


You can even run arbitrary code to decide whether to include a file or not with the e or + glob qualifier. However, when the wildcard pattern is used in a for loop, it's clearer to put the filtering code at the top of the loop body.



¹ You could put setopt extended_glob in ~/.zshenv, but I strongly recommend against using .zshenv, because any script that makes assumptions about what's in there would break on a different machine or a different account.

² If you're writing a zsh completion function, these run in an environment where extended_glob is turned on.






share|improve this answer

























  • *^.jpg would expand to all the files whose name ends in ^.jpg without extendedglob and all files with extentedglob, even file.jpg as that's for instance the empty string (matched by *) followed by file.jpg (matched by ^.jpg as that's not .jpg) (or file.jpg followed by the empty string, or file.jp followed by g, etc.).

    – Stéphane Chazelas
    Mar 8 at 9:40














4












4








4







Zsh provides very nice ways to enumerate files. They're documented in the manual under “Filename Generation”, but the zsh manual isn't very easy to follow.



By default, if there are no matching files, you'll get an error, which is often desirable on the command line, but not in scripts. To disable this error, either put this near the beginning of your script to turn on the null_glob option:



setopt null_glob

for x in *; do …


or use the N glob qualifier:



# Reliably iterate over non-dot files
for x in *(N); do …


Either snippet above iterates over all the files in the current directory that are not dot files. If there is no such file, the loop doesn't run at all (unlike sh where the loop body unhelpfully runs once on the unexpanded glob *, and default zsh where the glob causes an error).



To include dot files in the iteration, either turn on the got_glob option or use the D glob qualifier.



# Reliably iterate over all files in the current directory
for x in *(DN); do …


I recommend the glob qualifier method, even if it's more verbose, because it will keep behaving the same way even if you copy-paste that snippet to a script that didn't turn on the same options.



To exclude certain files based on their name, you can use the glob operators ^ and ~. Note that these require setopt extended_glob in your script² (this is not inherited from your runtime environment or your .zshrc¹). For example, to exclude *.jpg files, either write *~*.jpg or ^*.jpg.



(Note that what you wrote, *^.jpg, would by default cause an error in zsh. If you're seeing *^.jpg printed out, then either you're running zsh with nomatch turned off (it's on by default), which is normally only done when emulating sh or ksh, or else you're actually running that script under an sh shell, probably because it's missing a shebang line at the top.)



setopt extended_glob
# Iterate over all the files in the current directory except *.jpg and .*
for x in *~*.jpg(N); do …


If you want to traverse subdirectories recursively, it's easy: just use **/.



setopt extended_glob
# Iterate over all the files in the current directory and its (grand-)*children except *.jpg and .*
for x in **/*~*.jpg(N); do …


Through glob qualifiers, you can also select files based on conditions other than their name. For example, to loop over regular files only, excluding directories, symbolic links, etc.:



# Iterate over all regular files in the current directory and its (grand-)*children except *.jpg and .*
for x in **/*(.DN); do …


You can even run arbitrary code to decide whether to include a file or not with the e or + glob qualifier. However, when the wildcard pattern is used in a for loop, it's clearer to put the filtering code at the top of the loop body.



¹ You could put setopt extended_glob in ~/.zshenv, but I strongly recommend against using .zshenv, because any script that makes assumptions about what's in there would break on a different machine or a different account.

² If you're writing a zsh completion function, these run in an environment where extended_glob is turned on.






share|improve this answer















Zsh provides very nice ways to enumerate files. They're documented in the manual under “Filename Generation”, but the zsh manual isn't very easy to follow.



By default, if there are no matching files, you'll get an error, which is often desirable on the command line, but not in scripts. To disable this error, either put this near the beginning of your script to turn on the null_glob option:



setopt null_glob

for x in *; do …


or use the N glob qualifier:



# Reliably iterate over non-dot files
for x in *(N); do …


Either snippet above iterates over all the files in the current directory that are not dot files. If there is no such file, the loop doesn't run at all (unlike sh where the loop body unhelpfully runs once on the unexpanded glob *, and default zsh where the glob causes an error).



To include dot files in the iteration, either turn on the got_glob option or use the D glob qualifier.



# Reliably iterate over all files in the current directory
for x in *(DN); do …


I recommend the glob qualifier method, even if it's more verbose, because it will keep behaving the same way even if you copy-paste that snippet to a script that didn't turn on the same options.



To exclude certain files based on their name, you can use the glob operators ^ and ~. Note that these require setopt extended_glob in your script² (this is not inherited from your runtime environment or your .zshrc¹). For example, to exclude *.jpg files, either write *~*.jpg or ^*.jpg.



(Note that what you wrote, *^.jpg, would by default cause an error in zsh. If you're seeing *^.jpg printed out, then either you're running zsh with nomatch turned off (it's on by default), which is normally only done when emulating sh or ksh, or else you're actually running that script under an sh shell, probably because it's missing a shebang line at the top.)



setopt extended_glob
# Iterate over all the files in the current directory except *.jpg and .*
for x in *~*.jpg(N); do …


If you want to traverse subdirectories recursively, it's easy: just use **/.



setopt extended_glob
# Iterate over all the files in the current directory and its (grand-)*children except *.jpg and .*
for x in **/*~*.jpg(N); do …


Through glob qualifiers, you can also select files based on conditions other than their name. For example, to loop over regular files only, excluding directories, symbolic links, etc.:



# Iterate over all regular files in the current directory and its (grand-)*children except *.jpg and .*
for x in **/*(.DN); do …


You can even run arbitrary code to decide whether to include a file or not with the e or + glob qualifier. However, when the wildcard pattern is used in a for loop, it's clearer to put the filtering code at the top of the loop body.



¹ You could put setopt extended_glob in ~/.zshenv, but I strongly recommend against using .zshenv, because any script that makes assumptions about what's in there would break on a different machine or a different account.

² If you're writing a zsh completion function, these run in an environment where extended_glob is turned on.







share|improve this answer














share|improve this answer



share|improve this answer








edited Mar 8 at 9:26

























answered Mar 6 at 13:38









GillesGilles

545k12911071623




545k12911071623












  • *^.jpg would expand to all the files whose name ends in ^.jpg without extendedglob and all files with extentedglob, even file.jpg as that's for instance the empty string (matched by *) followed by file.jpg (matched by ^.jpg as that's not .jpg) (or file.jpg followed by the empty string, or file.jp followed by g, etc.).

    – Stéphane Chazelas
    Mar 8 at 9:40


















  • *^.jpg would expand to all the files whose name ends in ^.jpg without extendedglob and all files with extentedglob, even file.jpg as that's for instance the empty string (matched by *) followed by file.jpg (matched by ^.jpg as that's not .jpg) (or file.jpg followed by the empty string, or file.jp followed by g, etc.).

    – Stéphane Chazelas
    Mar 8 at 9:40

















*^.jpg would expand to all the files whose name ends in ^.jpg without extendedglob and all files with extentedglob, even file.jpg as that's for instance the empty string (matched by *) followed by file.jpg (matched by ^.jpg as that's not .jpg) (or file.jpg followed by the empty string, or file.jp followed by g, etc.).

– Stéphane Chazelas
Mar 8 at 9:40






*^.jpg would expand to all the files whose name ends in ^.jpg without extendedglob and all files with extentedglob, even file.jpg as that's for instance the empty string (matched by *) followed by file.jpg (matched by ^.jpg as that's not .jpg) (or file.jpg followed by the empty string, or file.jp followed by g, etc.).

– Stéphane Chazelas
Mar 8 at 9:40


















draft saved

draft discarded
















































Thanks for contributing an answer to Unix & Linux Stack Exchange!


  • Please be sure to answer the question. Provide details and share your research!

But avoid


  • Asking for help, clarification, or responding to other answers.

  • Making statements based on opinion; back them up with references or personal experience.

To learn more, see our tips on writing great answers.




draft saved


draft discarded














StackExchange.ready(
function ()
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2funix.stackexchange.com%2fquestions%2f504704%2fzsh-loop-files-ignore-certain-patterns-no-ls-or-find%23new-answer', 'question_page');

);

Post as a guest















Required, but never shown





















































Required, but never shown














Required, but never shown












Required, but never shown







Required, but never shown

































Required, but never shown














Required, but never shown












Required, but never shown







Required, but never shown






Popular posts from this blog

How to check contact read email or not when send email to Individual?

Bahrain

Postfix configuration issue with fips on centos 7; mailgun relay