LinuxQuestions.org
Help answer threads with 0 replies.
Home Forums Tutorials Articles Register
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-12-2012, 12:16 PM   #1
farmkid
LQ Newbie
 
Registered: Apr 2012
Posts: 3

Rep: Reputation: Disabled
extract directory name from path in script


I'm trying to write a script to automate some analysis of some stuff I do for work. The system passes on a path from an earlier step in the form of an environment variable that I need. However, what I need is a directory further up the path, not the full path, so I would like to extract that directory name.

Here is an example of the information that's passed: /data/R_2012_03_20_22_03_14_FLX03090507_Administrator_AA14-17_21-22_HLA1_4/D_2012_03_20_22_05_21_FLX03090507_imageProcessingOnlyAmplicons/regions/

What I need is the directory beginning with R (R_2012_03_20_22_03_14_FLX03090507_Administrator_AA14-17_21-22_HLA1_4). I need this so that I can search that directory for a group of files to copy to another location. Finding those files and copying them isn't a problem, I just need to tell it where to look.
 
Old 04-12-2012, 12:23 PM   #2
MensaWater
LQ Guru
 
Registered: May 2005
Location: Atlanta Georgia USA
Distribution: Redhat (RHEL), CentOS, Fedora, CoreOS, Debian, FreeBSD, HP-UX, Solaris, SCO
Posts: 7,831
Blog Entries: 15

Rep: Reputation: 1669Reputation: 1669Reputation: 1669Reputation: 1669Reputation: 1669Reputation: 1669Reputation: 1669Reputation: 1669Reputation: 1669Reputation: 1669Reputation: 1669
Code:
echo $VAR |awk -F/ '{print $3}'
Where $VAR is the name of the variable that contains the path.

Note the awk strips the "/" from each component of the path (because it is being told to use that as a field separator) including the first one so if you need that you might set it by adding it back in the print:

Code:
echo $VAR |awk -F/ '{print "/"$3}'
Also be aware of dirname and basename commands. The former gives you the path to the file (entire path without the file name at end) and the latter gives you just the file name at the end of the path.

Last edited by MensaWater; 04-12-2012 at 12:26 PM.
 
Old 04-12-2012, 12:26 PM   #3
colucix
LQ Guru
 
Registered: Sep 2003
Location: Bologna
Distribution: CentOS 6.5 OpenSuSE 12.3
Posts: 10,509

Rep: Reputation: 1983Reputation: 1983Reputation: 1983Reputation: 1983Reputation: 1983Reputation: 1983Reputation: 1983Reputation: 1983Reputation: 1983Reputation: 1983Reputation: 1983
If it is the only item in the path beginning with R, you can try something like this:
Code:
$ VAR=/data/R_2012_03_20_22_03_14_FLX03090507_Administrator_AA14-17_21-22_HLA1_4/D_2012_03_20_22_05_21_FLX03090507_imageProcessingOnlyAmplicons/regions/
$ echo $VAR | sed -r 's:.*/(R[^/]+)/.*:\1:'
R_2012_03_20_22_03_14_FLX03090507_Administrator_AA14-17_21-22_HLA1_4
On the other hand, if it is always the item after /data, using awk will be easier:
Code:
$ echo $VAR | awk -F/ '{print $3}'
R_2012_03_20_22_03_14_FLX03090507_Administrator_AA14-17_21-22_HLA1_4
 
Old 04-12-2012, 01:01 PM   #4
grail
LQ Guru
 
Registered: Sep 2009
Location: Perth
Distribution: Manjaro
Posts: 10,008

Rep: Reputation: 3193Reputation: 3193Reputation: 3193Reputation: 3193Reputation: 3193Reputation: 3193Reputation: 3193Reputation: 3193Reputation: 3193Reputation: 3193Reputation: 3193
Well I can think of 2 ways in bash:
Code:
VAR=/data/R_2012_03_20_22_03_14_FLX03090507_Administrator_AA14-17_21-22_HLA1_4/D_2012_03_20_22_05_21_FLX03090507_imageProcessingOnlyAmplicons/regions/

#1 Assuming directory is always after /data
dir1=${VAR#/*/}

echo "${dir1%%/*}"

#2 Assuming it could be anywhere in the path but the first one starting with an 'R'
match='/(R[^/]+)'

[[ $VAR =~ $match ]] && dir2=${BASH_REMATCH[1]}

echo "$dir2"
And an alternate awk solution (using same VAR):
Code:
echo "$VAR" | awk 'NR == 3' RS="/"

Last edited by grail; 04-12-2012 at 01:04 PM.
 
Old 04-12-2012, 06:14 PM   #5
farmkid
LQ Newbie
 
Registered: Apr 2012
Posts: 3

Original Poster
Rep: Reputation: Disabled
Thanks guys. It seems there are several ways to do it. I tried a few of the suggestions and got it work just as I want it to.

The variety of suggestions is good for me as well because I can study them to understand how they work and learn something about how the various tools work.
 
1 members found this post helpful.
Old 04-12-2012, 06:18 PM   #6
chrism01
LQ Guru
 
Registered: Aug 2004
Location: Sydney
Distribution: Rocky 9.2
Posts: 18,362

Rep: Reputation: 2751Reputation: 2751Reputation: 2751Reputation: 2751Reputation: 2751Reputation: 2751Reputation: 2751Reputation: 2751Reputation: 2751Reputation: 2751Reputation: 2751
Just as another way (assuming its always 2nd dir as above)
Code:
echo /dat/rdir/ddir |cut -d'/' -f3
 
Old 04-13-2012, 11:32 AM   #7
David the H.
Bash Guru
 
Registered: Jun 2004
Location: Osaka, Japan
Distribution: Arch + Xfce
Posts: 6,852

Rep: Reputation: 2037Reputation: 2037Reputation: 2037Reputation: 2037Reputation: 2037Reputation: 2037Reputation: 2037Reputation: 2037Reputation: 2037Reputation: 2037Reputation: 2037
See this link for a long list of built-in bash string manipulations. Your challenge here is to split up the string into individual directory elements, and output only the ones you want. In addition to the suggestions grail gave above, you could use an array, or read, and perhaps a few others.

http://mywiki.wooledge.org/BashFAQ/100


Here's a quick example function I just wrote up using an array:
Code:
extractpath(){

     #print an arbitrary number of levels from a given file path
     #$1 is the path, $2 is the number of levels to print

     local IFS='/'
     local -a path=( $1 )

     echo "/${path[*]:1:$2}"

}

$ extractpath "/home/david/temp/test/foo/bar/baz" 4
/home/david/temp/test
And here's an example of how to use read (and a here string to pass the pathname to it):

Code:
$ IFS='/' read _ a b c d e _ <<<"/home/david/temp/test/foo/bar/baz"
$ echo "/$a/$b/$c/$d/$e"
/home/david/temp/test/foo
Note that you could also just use read's -a option to load an array instead.

Also notice that when IFS is set to anything other than whitespace, then the empty string in front of the first delimiter is treated as the first entry. That's why the echoing of the array in the function starts with field 1, and the disposable "_" variable is included at the start in the read command (as well as at the end, where it catches all the trailing fields we don't want).


Finally, one more way to grab arbitrary numbers of levels, using parameter expansion:

Code:
$ fullpath='/home/david/temp/test/foo/bar/baz/'
$ keeppath="${fullpath#/*/*/*/}"	#use the desired number of /*/ levels you want to keep
$ echo "${fullpath%$keeppath}"
/home/david/temp/
Be careful with this one though. The exact pattern you need to use depends on whether the fullpath has a trailing slash or not.

Last edited by David the H.; 04-13-2012 at 11:42 AM.
 
  


Reply



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
shell script is defined in someother directory, how it is being invoked with path? vaibhavs17 Linux - Newbie 2 05-30-2011 10:24 PM
[SOLVED] Shell Script - Use variable in a for loop with directory path Tech109 Linux - General 2 01-19-2011 10:22 AM
Script cannot find directory path mike2008 Linux - Newbie 7 04-29-2009 12:12 PM
Shell script help: How to pass a directory path to the script? dv502 Programming 13 09-10-2008 03:07 AM
Discovering Script Directory Path WayneK Programming 9 07-14-2008 09:18 AM

LinuxQuestions.org > Forums > Linux Forums > Linux - Newbie

All times are GMT -5. The time now is 05:36 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