LinuxQuestions.org
Latest LQ Deal: Latest LQ Deals
Home Forums Tutorials Articles Register
Go Back   LinuxQuestions.org > Forums > Linux Forums > Linux - General
User Name
Password
Linux - General This Linux forum is for general Linux questions and discussion.
If it is Linux Related and doesn't seem to fit in any other forum then this is the place.

Notices


Reply
  Search this Thread
Old 08-15-2020, 04:27 AM   #1
linustalman
LQ Guru
 
Registered: Mar 2010
Location: Ireland
Distribution: Debian 12 Bookworm
Posts: 5,726

Rep: Reputation: 479Reputation: 479Reputation: 479Reputation: 479Reputation: 479
Question Code to only show files with 'nana' in name and not 'nana jane' or 'nana joan'.


Hi.

I want to rename my many photos to easily find all photos of a certain grandparent (not real names used in title). So any photos that only have 'nana', I want to find and rename manually to 'nana jane', etc.

I'd greatly appreciate a command line to achieve this.

Thanks.
 
Old 08-15-2020, 04:58 AM   #2
Turbocapitalist
LQ Guru
 
Registered: Apr 2005
Distribution: Linux Mint, Devuan, OpenBSD
Posts: 7,330
Blog Entries: 3

Rep: Reputation: 3726Reputation: 3726Reputation: 3726Reputation: 3726Reputation: 3726Reputation: 3726Reputation: 3726Reputation: 3726Reputation: 3726Reputation: 3726Reputation: 3726
The find utility can do boolean logic. See -a, -not, and -o in 'man find'. There is no XOR though. There is an implied AND between each option used when running find, so if you need an OR someday, you'll have to add in parenthesis to achieve the right grouping.

Code:
find ~/Pictures/ -type f -name '*.jpeg' -name '*nana*' -not -name '*jane*' -not -name '*joan*' -print
Then you could combine that with the rename utility, hopefully the perl-based one.

Last edited by Turbocapitalist; 08-15-2020 at 05:06 AM. Reason: POSIX compliance
 
1 members found this post helpful.
Old 08-15-2020, 05:57 AM   #3
berndbausch
LQ Addict
 
Registered: Nov 2013
Location: Tokyo
Distribution: Mostly Ubuntu and Centos
Posts: 6,316

Rep: Reputation: 2002Reputation: 2002Reputation: 2002Reputation: 2002Reputation: 2002Reputation: 2002Reputation: 2002Reputation: 2002Reputation: 2002Reputation: 2002Reputation: 2002
find is too difficult when the temperature is above 35 degrees Celsius.
Code:
ls -R | grep 'nana.*jpe*g$' | grep -v -e jane -e joan
 
1 members found this post helpful.
Old 08-15-2020, 06:00 AM   #4
pan64
LQ Addict
 
Registered: Mar 2012
Location: Hungary
Distribution: debian/ubuntu/suse ...
Posts: 21,930

Rep: Reputation: 7321Reputation: 7321Reputation: 7321Reputation: 7321Reputation: 7321Reputation: 7321Reputation: 7321Reputation: 7321Reputation: 7321Reputation: 7321Reputation: 7321
or you can rename all nana to nana jane and afterward rename [back] nana jane joan to nana joan.
you only need to use the command rename to do that.
 
Old 08-15-2020, 07:50 AM   #5
boughtonp
Senior Member
 
Registered: Feb 2007
Location: UK
Distribution: Debian
Posts: 3,616

Rep: Reputation: 2554Reputation: 2554Reputation: 2554Reputation: 2554Reputation: 2554Reputation: 2554Reputation: 2554Reputation: 2554Reputation: 2554Reputation: 2554Reputation: 2554

The existing answers do not give you what was actually asked for - they all wrongly exclude combinations like "joanna and nana" and wrongly include matches for results like "banana", and the obvious change would still wrongly exclude "nana joan and nana" from matching, which may or not occur but isn't difficult to cope with.

To search specifically for "nana" as a word and without jane or joan following it, you can use a regex with word boundary markers and negative lookahead: "\bnana\b(?! jane| joan)" or (useful if there might be more names): "\bnana\b(?! (jane|joan)\b)"

You can't use that with find because none of the 13 regex variants find allows have support for negative lookaheads, but you can easily filter with grep's Perl-compatible mode:

Code:
find ~/Pictures/ -type f -iname '*nana*' | grep -iP '\bnana\b(?! jane| joan)'
Or indeed using the recursive ls approach:
Code:
ls -R | grep -iP '\bnana\b(?! jane| joan)'
If you need to limit to JPEG files, the pattern should be suffixed with ".*\.jpe?g$" - but if these are scanned images they're as likely to be TIFFs or perhaps something else, so I've not bothered specifying the extension. If it's necessary you could use something like ".*\.(jpe?g|tiff?|tga|whatever)$"

Also, you probably want a case-insensitive search, so there's -i on the grep and -iname used for the find.

 
1 members found this post helpful.
Old 08-15-2020, 09:13 AM   #6
linustalman
LQ Guru
 
Registered: Mar 2010
Location: Ireland
Distribution: Debian 12 Bookworm
Posts: 5,726

Original Poster
Rep: Reputation: 479Reputation: 479Reputation: 479Reputation: 479Reputation: 479
Thumbs up

Quote:
Originally Posted by boughtonp View Post

...

Or indeed using the recursive ls approach:
Code:
ls -R | grep -iP '\bnana\b(?! jane| joan)'
...
Hi boughtonp.

That's the solution right there! Kudos and thank you!

Thanks to all for posting.

Last edited by linustalman; 08-15-2020 at 09:16 AM.
 
Old 08-15-2020, 09:22 AM   #7
dugan
LQ Guru
 
Registered: Nov 2003
Location: Canada
Distribution: distro hopper
Posts: 11,241

Rep: Reputation: 5322Reputation: 5322Reputation: 5322Reputation: 5322Reputation: 5322Reputation: 5322Reputation: 5322Reputation: 5322Reputation: 5322Reputation: 5322Reputation: 5322
I don't have a solution, but it might be easier if you start with Ripgrep, which has full PCRE2 support.

Last edited by dugan; 08-15-2020 at 03:13 PM.
 
Old 08-15-2020, 09:34 AM   #8
Turbocapitalist
LQ Guru
 
Registered: Apr 2005
Distribution: Linux Mint, Devuan, OpenBSD
Posts: 7,330
Blog Entries: 3

Rep: Reputation: 3726Reputation: 3726Reputation: 3726Reputation: 3726Reputation: 3726Reputation: 3726Reputation: 3726Reputation: 3726Reputation: 3726Reputation: 3726Reputation: 3726
Quote:
Originally Posted by boughtonp View Post
To search specifically for "nana" as a word and without jane or joan following it, you can use a regex with word boundary markers and negative lookahead: "\bnana\b(?! jane| joan)" or (useful if there might be more names): "\bnana\b(?! (jane|joan)\b)"
Looking at that requirement I see that find is missing any options at all for recognizing word boundaries, not just negative lookaheads, in its regular expression pattern matching.

It is possible to use grep with find, though it might not be so efficient:

Code:
find ~/Pictures -type f -name '*nana*' -exec sh -c 'echo {} | grep -q -P "\bnana\b(?! (jane|joan)\b)"' \; -print
 
Old 08-15-2020, 09:40 AM   #9
linustalman
LQ Guru
 
Registered: Mar 2010
Location: Ireland
Distribution: Debian 12 Bookworm
Posts: 5,726

Original Poster
Rep: Reputation: 479Reputation: 479Reputation: 479Reputation: 479Reputation: 479
Quote:
Originally Posted by Turbocapitalist View Post
Looking at that requirement I see that find is missing any options at all for recognizing word boundaries, not just negative lookaheads, in its regular expression pattern matching.

It is possible to use grep with find, though it might not be so efficient:

Code:
find ~/Pictures -type f -name '*nana*' -exec sh -c 'echo {} | grep -q -P "\bnana\b(?! (jane|joan)\b)"' \; -print
Hi TC.

Output:
Code:
sh: 1: Syntax error: "(" unexpected
sh: 1: Syntax error: "(" unexpected
sh: 1: Syntax error: "(" unexpected
I'll go with boughtonp's suggestion.
 
Old 08-15-2020, 02:15 PM   #10
boughtonp
Senior Member
 
Registered: Feb 2007
Location: UK
Distribution: Debian
Posts: 3,616

Rep: Reputation: 2554Reputation: 2554Reputation: 2554Reputation: 2554Reputation: 2554Reputation: 2554Reputation: 2554Reputation: 2554Reputation: 2554Reputation: 2554Reputation: 2554
Quote:
Originally Posted by Turbocapitalist View Post
Looking at that requirement I see that find is missing any options at all for recognizing word boundaries, not just negative lookaheads, in its regular expression pattern matching.
Not sure if the default regextype varies, but -regextype sed will allow \b word boundaries with find.

Some of the others engines don't support \b but do have \< and \> for start and end boundaries respectively.

 
  


Reply

Tags
code



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 On
HTML code is Off



Similar Threads
Thread Thread Starter Forum Replies Last Post
LXer: Jane Austen on Python: The intersection of literature and tech LXer Syndicated Linux News 0 10-06-2015 01:11 PM
LXer: Joan Touzet on CouchDB and the Apache way LXer Syndicated Linux News 0 08-18-2015 10:06 AM
LXer: Ubuntu 12.04 â?? Jane Silber talks Unity, community and â??continuous computingâ?? LXer Syndicated Linux News 0 04-24-2012 01:20 PM
Fedora Core 4, source compile kernel 2.6 (jane) fr0zen Fedora 2 11-08-2005 06:45 PM
Apache Help - Dick and Jane Style phar1944 Linux - Networking 2 01-25-2003 03:51 PM

LinuxQuestions.org > Forums > Linux Forums > Linux - General

All times are GMT -5. The time now is 03:02 PM.

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
Open Source Consulting | Domain Registration