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 07-07-2010, 12:34 AM   #1
paul.richter
LQ Newbie
 
Registered: Sep 2009
Location: Tokyo
Distribution: slackware 12.1
Posts: 4

Rep: Reputation: 0
Escaping the parentheses characters in a bash script which calls find with -prune


I have a bash script which calls the 'find' command with multiple directories to prune.

Here is the entire script:

Code:
#!/bin/bash

SRCDIR="$HOME/test"
PRED="-wholename '$SRCDIR/skip1' -o -wholename '$SRCDIR/skip2'"

echo find $SRCDIR '\(' $PRED '\)' -prune -or -print
find $SRCDIR '(' $PRED ')' -prune -or -print
I have under SRCDIR the directories skip1, skip2, look1, and look2, each with a few files in it.

If I run the script and paste the echoed line into the bash prompt, it will print out:
Code:
/home/paul/test
/home/paul/test/skip1
/home/paul/test/look2
/home/paul/test/look2/file2.txt
/home/paul/test/look2/file1.txt
/home/paul/test/skip2
/home/paul/test/look1
/home/paul/test/look1/file2.txt
/home/paul/test/look1/file1.txt
I understand that the parentheses \( and \) need to be escaped to protect them from the shell, and this is the result I want.

I want the next line in the script to do the exact same thing, but called from the script. But the result is :
Code:
/home/paul/test
/home/paul/test/skip1
/home/paul/test/skip1/file2.txt
/home/paul/test/skip1/file1.txt
/home/paul/test/look2
/home/paul/test/look2/file2.txt
/home/paul/test/look2/file1.txt
/home/paul/test/skip2
/home/paul/test/skip2/file2.txt
/home/paul/test/skip2/file1.txt
/home/paul/test/look1
/home/paul/test/look1/file2.txt
/home/paul/test/look1/file1.txt
I can not figure out how to properly escape the parentheses characters within the script. I've tried all sorts of variations instead of '(' and ')', and here are the results:
( ... ) -> bash error: syntax error near unexpected token `('
'\(' ... '\)' -> find error: paths must precede expression
"\(" ... "\)" -> find error: paths must precede expression
\( ... \) -> same as '(' ... ')' , find prints out all directories

How can I properly tell find to treat the parentheses as precedence operators?
 
Old 07-07-2010, 12:40 AM   #2
paul.richter
LQ Newbie
 
Registered: Sep 2009
Location: Tokyo
Distribution: slackware 12.1
Posts: 4

Original Poster
Rep: Reputation: 0
I found the following workaround:

bash -c "find $SRCDIR \( $PRED \) -prune -or -print"

But this is just a horrible ugly hack, calling bash from within the script.
 
Old 07-07-2010, 12:50 AM   #3
konsolebox
Senior Member
 
Registered: Oct 2005
Distribution: Gentoo, Slackware, LFS
Posts: 2,245
Blog Entries: 16

Rep: Reputation: 233Reputation: 233Reputation: 233
try to cast eval for that:
Code:
eval "find $SRCDIR \( $PRED \) -prune -or -print"
edit: i think it's safer to use arrays:
Code:
#!/bin/bash

SRCDIR=$HOME/test
PRED=(-wholename "$SRCDIR/skip1" -o -wholename "$SRCDIR/skip2")

echo find "$SRCDIR" \( "${PRED[@]}" \) -prune -or -print
find "$SRCDIR" \( "${PRED[@]}" \) -prune -or -print

Last edited by konsolebox; 07-07-2010 at 12:52 AM.
 
Old 07-07-2010, 01:42 AM   #4
grail
Guru
 
Registered: Sep 2009
Location: Perth
Distribution: Manjaro
Posts: 7,692

Rep: Reputation: 1987Reputation: 1987Reputation: 1987Reputation: 1987Reputation: 1987Reputation: 1987Reputation: 1987Reputation: 1987Reputation: 1987Reputation: 1987Reputation: 1987
Is it just me or does the first post have the brackets NOT escaped??
Quote:
find $SRCDIR '(' $PRED ')' -prune -or -print
Now I am not saying it will definately work but you are comparing apples and oranges I believe.
 
Old 07-07-2010, 08:47 AM   #5
Andrew Benton
Senior Member
 
Registered: Aug 2003
Location: Birkenhead/Britain
Distribution: Linux From Scratch
Posts: 2,073

Rep: Reputation: 64
I can't test this 'cos I don't have the files to search, but I had a problem using find with ssh (I was tying to use find within a script to search for files on another computer). My solution was to escape the backslash with two more backslashes like this
Code:
file_list=($(ssh eccles find ~/save/sources \\\( -path ~/save/sources/.git -o -path \
  ~/save/sources/aspell6-en \\\) -prune -o -type f))
 
Old 07-07-2010, 09:20 AM   #6
grail
Guru
 
Registered: Sep 2009
Location: Perth
Distribution: Manjaro
Posts: 7,692

Rep: Reputation: 1987Reputation: 1987Reputation: 1987Reputation: 1987Reputation: 1987Reputation: 1987Reputation: 1987Reputation: 1987Reputation: 1987Reputation: 1987Reputation: 1987
This works:
Code:
#!/bin/bash

SRCDIR="$HOME/test"
PRED="-wholename $SRCDIR/skip1 -o -wholename $SRCDIR/skip2"

echo "find $SRCDIR \( $PRED \) -prune -or -print"
find $SRCDIR \( $PRED \) -prune -or -print
As usual we were getting too carried away with how to make it look right when exactly as you do it on the command line works just fine
 
Old 07-07-2010, 10:10 PM   #7
paul.richter
LQ Newbie
 
Registered: Sep 2009
Location: Tokyo
Distribution: slackware 12.1
Posts: 4

Original Poster
Rep: Reputation: 0
Thanks, grail.

I see the difference is the removed single-quoting of $SRCDIR/skip1. If it is quoted it will look in the skip directories. For my purposes not having the quotes will work, but I'm afraid if will fail on a directory with a space in its name. I guess that's a separate question though...I will work on it.
 
Old 07-07-2010, 10:19 PM   #8
grail
Guru
 
Registered: Sep 2009
Location: Perth
Distribution: Manjaro
Posts: 7,692

Rep: Reputation: 1987Reputation: 1987Reputation: 1987Reputation: 1987Reputation: 1987Reputation: 1987Reputation: 1987Reputation: 1987Reputation: 1987Reputation: 1987Reputation: 1987
You could try putting in escaped quotes (\") around the path to be excluded to help preserve the spaces.
 
Old 07-07-2010, 10:32 PM   #9
paul.richter
LQ Newbie
 
Registered: Sep 2009
Location: Tokyo
Distribution: slackware 12.1
Posts: 4

Original Poster
Rep: Reputation: 0
Quote:
Originally Posted by grail View Post
You could try putting in escaped quotes (\") around the path to be excluded to help preserve the spaces.
Nope, unescaped single quotes, escaped single quotes, escaped double quotes all cause find to look in the skip directories.
 
Old 07-07-2010, 10:59 PM   #10
grail
Guru
 
Registered: Sep 2009
Location: Perth
Distribution: Manjaro
Posts: 7,692

Rep: Reputation: 1987Reputation: 1987Reputation: 1987Reputation: 1987Reputation: 1987Reputation: 1987Reputation: 1987Reputation: 1987Reputation: 1987Reputation: 1987Reputation: 1987
Where there is a will there is a way
Code:
#!/bin/bash

SRCDIR="$HOME/test"
PRED="-wholename \"$SRCDIR/skip[12]\""

echo "find $SRCDIR \( $PRED \) -prune -or -print"
eval find $SRCDIR $PRED -prune -or -print
If you still need to have individual names you need to go nuts on the escaping:
Code:
eval find $SRCDIR \\\( $PRED \\\) -prune -or -print
Edit: hold the phone ... for the last example you can place your brackets in the variable:
Code:
PRED="\( -wholename \"$SRCDIR/skip1\" -o -wholename \"$SRCDIR/skip2\" \)"

Last edited by grail; 07-07-2010 at 11:03 PM.
 
  


Reply

Tags
bash, escape, find, prune


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
a script calls another script which calls "bash" inside lordofring Linux - Software 10 03-18-2010 10:59 AM
[SOLVED] Bash Script combination of sed with pwd command escaping slashes HaukeG Programming 2 10-06-2009 05:04 AM
bash script to find out more than 1 continuous special characters in a file. kkpal Linux - Newbie 1 06-02-2008 05:56 AM
escaping ':' character in bash script paulyche Linux - General 2 11-07-2006 08:18 AM
Bash script - escaping whitespaces colabus Linux - Newbie 15 04-30-2006 12:58 AM


All times are GMT -5. The time now is 06:35 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
identi.ca: @linuxquestions
Facebook: linuxquestions Google+: linuxquestions
Open Source Consulting | Domain Registration