LinuxQuestions.org
Share your knowledge at the LQ Wiki.
Go Back   LinuxQuestions.org > Forums > Linux Forums > Linux - Newbie
User Name
Password
Linux - Newbie This Linux forum is for members that are new to Linux.
Just starting out and have a question? If it is not in the man pages or the how-to's this is the place!

Notices


Reply
  Search this Thread
Old 04-09-2016, 03:30 PM   #1
beca123456
LQ Newbie
 
Registered: Apr 2016
Posts: 9

Rep: Reputation: Disabled
BASH: if statement in a for loop


I am sure it is a very basic question, but I checked a lot of threads and could not find an answer.

For files in a directory, how to process them if their filename do NOT contain a pattern?

I tried something like this so far:
Code:
for A in /path/to/*.txt; do if [[ ls | grep -v \^pattern.\ ${A} ]] then; <command ${A}>; fi; done
I keep getting 'unexpected token ', 'syntax error near '|' or 'conditional binary operator expected' messages.

Last edited by beca123456; 04-09-2016 at 04:07 PM.
 
Old 04-09-2016, 04:07 PM   #2
Michael Uplawski
Member
 
Registered: Dec 2015
Distribution: Debian stretch/sid
Posts: 436
Blog Entries: 9

Rep: Reputation: 275Reputation: 275Reputation: 275
Quote:
Originally Posted by beca123456 View Post
For files in a directory, how to process them if their filename do NOT contain a pattern?
You can negate a pattern with '!', like in
Code:
for f in `ls [!pattern]*`; do echo "$f"; done
PSE tell me if this still causes problems.
 
1 members found this post helpful.
Old 04-09-2016, 04:12 PM   #3
beca123456
LQ Newbie
 
Registered: Apr 2016
Posts: 9

Original Poster
Rep: Reputation: Disabled
Awesome ! Thanks Michael !

Last edited by beca123456; 04-09-2016 at 04:20 PM.
 
Old 04-09-2016, 04:24 PM   #4
Michael Uplawski
Member
 
Registered: Dec 2015
Distribution: Debian stretch/sid
Posts: 436
Blog Entries: 9

Rep: Reputation: 275Reputation: 275Reputation: 275
Quote:
Originally Posted by beca123456 View Post
ls works only for the current directory, right?
That is not your real problem, you can extend my example from above to
Code:
for f in `ls /path/to/the/directory/[!file_pattern]*`; do echo "$f"; done
then call the script from wherever you like.

But if you plan to re-use this under changing conditions, it will be interesting, how you compose your pattern each time. I am not really sure, but have a bad feeling about the negation. It may introduce more potential for false “positives” than without... Maybe it is wiser to move the unwanted files away from the directory, then just process the remainder...
This is really strange; as if I had made some bad experience with such a match one time but cannot remember any more...
 
Old 04-09-2016, 06:22 PM   #5
cnamejj
Member
 
Registered: Mar 2015
Distribution: Ubuntu
Posts: 37

Rep: Reputation: Disabled
Here's an alternate method that might be interesting to see. It's more like how my brain works, so (at least for me) it's more readable.

Code:
for FN in $(ls /path/to/*.txt | awk '!/pattern/'); do <command ${FN}>; done
If the file names have spaces in them it won't work. I can post a minor tweak way to deal with that if there's interest.
 
Old 04-09-2016, 07:09 PM   #6
grail
LQ Guru
 
Registered: Sep 2009
Location: Perth
Distribution: Manjaro
Posts: 9,421

Rep: Reputation: 2815Reputation: 2815Reputation: 2815Reputation: 2815Reputation: 2815Reputation: 2815Reputation: 2815Reputation: 2815Reputation: 2815Reputation: 2815Reputation: 2815
For both posts 2, 4 and 5 one will hope that none of the output of `` or $() is separated by white space, otherwise the command will be working on something that does not exist.

I have to say that from the original example provided I am not sure I understand the task?
Code:
ls | grep -v \^pattern.\ ${A}
The above makes little to no sense. List all items in the current directory and negate a grep on the output that does not contain '^pattern /path/to/abc.txt'. My question is why you would have
any files or directories that would contain such a pattern?

Are you able to perhaps explain, perhaps with example data, exactly what it is you are after?
 
Old 04-09-2016, 08:10 PM   #7
cnamejj
Member
 
Registered: Mar 2015
Distribution: Ubuntu
Posts: 37

Rep: Reputation: Disabled
To handle files with spaces in the names, this variant should work.

Code:
ls /path/to/*.txt | awk '!/pattern/' | while read FN; do <command ${FN}>; done
But I prefer to avoid having "while read" get data from a pipeline whenever possible though. I've run into problems where some commands inside the "do/done" loop can screw up the data in the pipeline, essentially terminating the loop after the first time through.

In my experience it will either work or break every time, so it's easy enough to test before you start using the script. But I still prefer to avoid that sort of construct where I can.
 
Old 04-09-2016, 08:38 PM   #8
ntubski
Senior Member
 
Registered: Nov 2005
Distribution: Arch
Posts: 3,055

Rep: Reputation: 1266Reputation: 1266Reputation: 1266Reputation: 1266Reputation: 1266Reputation: 1266Reputation: 1266Reputation: 1266Reputation: 1266
Quote:
Originally Posted by Michael Uplawski View Post
You can negate a pattern with '!', like in
Code:
for f in `ls [!pattern]*`; do echo "$f"; done
PSE tell me if this still causes problems.
It's a bit misleading to say that negates a pattern. The ! complements a character set, so [!pattern]* matches any file that doesn't start with one a,e,n,p,r, or t. The `ls ...` is redundant, you can get the same with
Code:
for f in [!pattern]*; do echo "$f"; done
except that this version can handle file names with spaces.
Quote:
[…]

Matches any one of the enclosed characters. ... If the first character following the ‘[’ is a ‘!’ or a ‘^’ then any character not enclosed is matched.

http://www.gnu.org/software/bash/man...-Matching.html

If you enable extglob, !(pattern-list) gives you actual pattern negation.
 
1 members found this post helpful.
Old 04-09-2016, 08:44 PM   #9
grail
LQ Guru
 
Registered: Sep 2009
Location: Perth
Distribution: Manjaro
Posts: 9,421

Rep: Reputation: 2815Reputation: 2815Reputation: 2815Reputation: 2815Reputation: 2815Reputation: 2815Reputation: 2815Reputation: 2815Reputation: 2815Reputation: 2815Reputation: 2815
cnamejj's last post seems to make it clearer what is being attempted, but I still like to keep things simple:
Code:
pattern=<regex here>

for FN in /path/to/*.txt
do
  [[ "$FN" =~ $pattern ]] || <command "$FN">
done

Last edited by grail; 04-09-2016 at 08:45 PM.
 
Old 04-10-2016, 02:32 AM   #10
Michael Uplawski
Member
 
Registered: Dec 2015
Distribution: Debian stretch/sid
Posts: 436
Blog Entries: 9

Rep: Reputation: 275Reputation: 275Reputation: 275
Quote:
Originally Posted by ntubski View Post
The ! complements a character set, so [!pattern]* matches any file that doesn't start with one a,e,n,p,r, or t.
Thank you. This distinction is important.
Quote:
If you enable extglob, !(pattern-list) gives you actual pattern negation.
The specific needs of the OP had not been too clear, in this respect. Anyway, it happens often, that we respond to a question, and many follow, before the OP explains why all our responses are “not quite what he needs”.
The original example lets much space for imagination. A temptation that I try to resist.
 
  


Reply


Thread Tools Search this Thread
Search this Thread:

Advanced Search

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is Off
HTML code is Off



Similar Threads
Thread Thread Starter Forum Replies Last Post
[SOLVED] Bash programming: If statement within a while loop shakozzz Programming 10 11-19-2014 12:21 PM
[SOLVED] Using while loop & select statement - Loop issues Kustom42 Programming 4 05-17-2013 09:43 AM
Need help with for loop + if statement Thaidog Programming 5 05-06-2011 10:54 PM
Run SQL update statement in a for loop in bash testac Programming 8 06-11-2010 11:18 AM
BASH Need help figuring out how to loop SELECT statement mcdrr Programming 2 05-08-2007 05:47 AM


All times are GMT -5. The time now is 10:54 AM.

Main Menu
Advertisement
My LQ
Write for LQ
LinuxQuestions.org is looking for people interested in writing Editorials, Articles, Reviews, and more. If you'd like to contribute content, let us know.
Main Menu
Syndicate
RSS1  Latest Threads
RSS1  LQ News
Twitter: @linuxquestions
Facebook: linuxquestions Google+: linuxquestions
Open Source Consulting | Domain Registration