LinuxQuestions.org
Did you know LQ has a Linux Hardware Compatibility List?
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
 
LinkBack Search this Thread
Old 07-06-2010, 11:34 PM   #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-06-2010, 11:40 PM   #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-06-2010, 11:50 PM   #3
konsolebox
Senior Member
 
Registered: Oct 2005
Distribution: Gentoo, Slackware, LFS
Posts: 2,242
Blog Entries: 15

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-06-2010 at 11:52 PM.
 
Old 07-07-2010, 12:42 AM   #4
grail
Guru
 
Registered: Sep 2009
Location: Perth
Distribution: Manjaro
Posts: 7,191

Rep: Reputation: 1784Reputation: 1784Reputation: 1784Reputation: 1784Reputation: 1784Reputation: 1784Reputation: 1784Reputation: 1784Reputation: 1784Reputation: 1784Reputation: 1784
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, 07: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, 08:20 AM   #6
grail
Guru
 
Registered: Sep 2009
Location: Perth
Distribution: Manjaro
Posts: 7,191

Rep: Reputation: 1784Reputation: 1784Reputation: 1784Reputation: 1784Reputation: 1784Reputation: 1784Reputation: 1784Reputation: 1784Reputation: 1784Reputation: 1784Reputation: 1784
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, 09: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, 09:19 PM   #8
grail
Guru
 
Registered: Sep 2009
Location: Perth
Distribution: Manjaro
Posts: 7,191

Rep: Reputation: 1784Reputation: 1784Reputation: 1784Reputation: 1784Reputation: 1784Reputation: 1784Reputation: 1784Reputation: 1784Reputation: 1784Reputation: 1784Reputation: 1784
You could try putting in escaped quotes (\") around the path to be excluded to help preserve the spaces.
 
Old 07-07-2010, 09: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, 09:59 PM   #10
grail
Guru
 
Registered: Sep 2009
Location: Perth
Distribution: Manjaro
Posts: 7,191

Rep: Reputation: 1784Reputation: 1784Reputation: 1784Reputation: 1784Reputation: 1784Reputation: 1784Reputation: 1784Reputation: 1784Reputation: 1784Reputation: 1784Reputation: 1784
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 10: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
Trackbacks are Off
Pingbacks are On
Refbacks are 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 09:59 AM
[SOLVED] Bash Script combination of sed with pwd command escaping slashes HaukeG Programming 2 10-06-2009 04:04 AM
bash script to find out more than 1 continuous special characters in a file. kkpal Linux - Newbie 1 06-02-2008 04:56 AM
escaping ':' character in bash script paulyche Linux - General 2 11-07-2006 07:18 AM
Bash script - escaping whitespaces colabus Linux - Newbie 15 04-29-2006 11:58 PM


All times are GMT -5. The time now is 12:17 AM.

Main Menu
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