-3

I want to loop through files matching a pattern. They can be in the current directory or sub directories.

I tried:

 for file in **/$_pat*; do

but it only finds files in sub directories. I also put the following command in bashrc and also in the script but it still doesn't work.

shopt -s globstar

shopt isn't recognized in the script.

shopt: not found                              
Ahmad
  • 8,811
  • 11
  • 76
  • 141
  • 1
    Use find: `find 'some-path' -type f -iname '*pattern*'` – 0stone0 Apr 10 '23 at 17:46
  • @Discussian I modified my question, the solution didn't work here – Ahmad Apr 10 '23 at 17:55
  • 1
    Non-interactive bash scripts don't usually read bashrc. You should put `shopt -s globstar` inside your script. – Discussian Apr 10 '23 at 17:57
  • @Discussian I put it in script and it didn't work, the accepted answwer is good, no duplicate – Ahmad Apr 11 '23 at 08:37
  • @Discussian My script is `sh` not `bash`, so the command isn't recognized there. – Ahmad Apr 11 '23 at 08:44
  • Well, you put "bash" in the title and tags, so... But yeah, `find` is more portable, that is true. – Discussian Apr 11 '23 at 09:18
  • If you would use sh instead of bash, both `**` and `shopt` would produce an error message; but in any case, when doing programming, don't **guess** what programming language you are using, but instead **decide** which one you are going to use. – user1934428 Apr 11 '23 at 09:37
  • @user1934428 Sorry What? Now I should list all my problems to convince you why I use a certain script? I just reported the problems. ** didn't produce any problem, and shopt did. that's it. – Ahmad Apr 11 '23 at 10:56
  • @Discussian changed bash to sh – Ahmad Apr 11 '23 at 10:59
  • @Ahmad: Don't get me wrong, but I found it confusing. In your first posting, you have tagged the script as _bash_, and you were posting bash commands. Now you are retagging it as _sh_, where bash commands don't make sense. That's why I say that you first have to make up your mind what language you are choosing, and then you can think of the commands to use. Actually, using bash or zsh **would** be a good idea for your problem, but if you insist, you can of course also solve it a bit more complicated in sh. – user1934428 Apr 11 '23 at 11:01
  • @user1934428 thanks, right! it was sh! and I had to use it correctly. But accept me, these terms are confusing and many times I solved my problems by searching for bash which is more common. – Ahmad Apr 11 '23 at 11:05
  • @user1934428 I just wonder who gives it down votes when it has solution and is not duplicate because those solutions don't work in sh – Ahmad Apr 11 '23 at 11:07
  • @Ahmad: Maybe silly question: Why are you forced to use sh? – user1934428 Apr 11 '23 at 11:08
  • I got some errors I can't remember, I think one was that `bash` didn't recognize `aliases` that I defined in the script. I can now check and say more – Ahmad Apr 11 '23 at 11:09
  • @Ahmad : A downvote can mean one of: The question does not exhibit good research effort. The question is unclear. The question is not useful. I think in your case, the main problem is that a question which (in its first version) was about bash, showed reasonable bash code, but no explanation in what way the code was wrong (you never showed an error message). Simply including the literal error message from your `shopt` would have told everyone that you are not using bash. Not providing a description of the "wrong behaviour" usually gets you a downvote. – user1934428 Apr 11 '23 at 11:11
  • @user1934428 modified the question. – Ahmad Apr 11 '23 at 11:20
  • @Ahmad : Now the question looks reasonable to me. I just wonder: Is the error message from `shopt` really _shopt: not found_, or is it something like _sh : shopt: not found_, or maybe _sh : command not found_? – user1934428 Apr 11 '23 at 11:25
  • It is `train.sh: 33: shopt: not found `, I even tested it with a new file like `#!/bin/sh shopt -s globstar` and got same error – Ahmad Apr 11 '23 at 12:02

1 Answers1

1

Use find:

find "$_path" -type f -iname "*your_pattern*"

Where:

-iname = case insensitive matching of a pattern

-type f = searches only regular files, omitting directories or links

To use it in a loop:

find "$_path" -type f -iname "*your_pattern*"|while read file
do
echo "$file"
done

for loop will not work if you have spaces in the results, while while reads each while line

Depending on what you want to do a an end goal, you can use the -exec in find like:

find "$_path" -type f -iname "*your_pattern*" -exec echo {} \;

where {} would represent the matching line/file`

Also you do ned the \; at the end

Ron
  • 5,900
  • 2
  • 20
  • 30
  • How to use it together with `for`? – Ahmad Apr 10 '23 at 17:56
  • I updated my answer, though you need to add more details and show what your end goal is... as we can provide here a lot of solutions but do not know which one best suits you – Ron Apr 10 '23 at 18:00
  • thanks, I will try it and accept or give feedback – Ahmad Apr 10 '23 at 18:01