getting the path part of an argument

Seems I'm inundating this forum with questions, but anyway:

I am writing a script that should accept one and only one argument when called.

That argument should designate a file, either with path/filename or just filename.

Now to the difficult bit:

I want to figure out a way to store just the path in one variable and just the file name in another. I need this for subsequent manipulation.

I thought I should be able to do this with sed or awk, but I couldn't figure it out.
Also, I am fundamentally unsure whether it's a good idea to just look for the last "/" in the argument.

So I'm going to ask the one question I am starting to get famous for: is there a better way to achieve what I want?

The below code is what I currently have, giving you the context this is for, not tremendously important, but just so you can see where I'm going:

if [ $# -eq 1 ] && [ -r "$1" ] && [ -f "$1" ] && [ `wc -c "$1" | awk '{print $1}'` -gt 681574400 ]; then 
# I should add a check whether the current dir is writable 
	# there is only one parameter AND it\'s writable AND it\'s an ordinary file AND it\'s bigger than 650MB
	split -b650m "$1" "$1"'.carved.'
	#echo "last error:"
	#echo $?
	# check how split reacts when given a file smaller than 650MB
	
	slices=( $(ls . | grep "$1.carved." | grep -v "rejoin.$1") )
		
	# echo "Number of slices:"
	slice_count=${#slices[@]}
	# echo $slice_count
	
	echo "#!/bin/sh" > "rejoin.$1"
	index=1
	while [ "$index" -lt "$slice_count" ]; do
		echo "cat ${slices[$index]} >> ${slices[0]}" >> "rejoin.$1"
		let "index = $index + 1"
	done
	echo "mv ${slices[0]} \"$1\"" >> "rejoin.$1"
	echo "exit" >> "rejoin.$1"
	chmod 755 "rejoin.$1"
	echo "Generated rejoin script."

	exit 0;
else
	echo "carve - carves up a (large) file into 650MB pieces";
	echo
	echo "usage: carve <filename>";
	echo 
	echo "carve also generates a \"rejoin\" script for future reassembly"; 
	# That's because I want the user to have no excuse for not including a 
	# surefire rejoin script when putting these files somewhere.
	# We don't want some other user end up with a bunch of confusing files
	# s/he doesn't know how to deal with.
	# This "included" generation out of this script is also to minimize 
	# dependencies.
	exit 1
fi

This works:

#!/bin/bash

INPUT="$1"

echo "Original : "${INPUT}
echo ""
echo "Without path : "${INPUT##/*/}
echo ""
echo "Path only : "${INPUT%/*}

$ cut-it /a/b/c/d/e/somefile
Original : /a/b/c/d/e/somefile

Without path : somefile

Path only : /a/b/c/d/e

Only works if a path is given with the filename....... But you might be able to work around that.

Should work for bash and ksh, check manpage (Parameter Expansion, near the bottom of the paragraph) for a more detailed explanation.

Hope it helps anyway :slight_smile:

Excellent! Good stuff!
:slight_smile:

btw, I found it's actually better to use:

INPUT="$1"

echo "Original : "${INPUT}
echo ""
echo "Without path : "${INPUT##*/}
echo ""
echo "Path only : "${INPUT%/*}

as this will take into account the possibility of only having a relative path (and not an absolute one) -- as in cut-it somedirectory/filetobecut

Or is there a reason why you had the two forward slashes?

Also, I still need to account for the possibility of the path being just "/" -- and of course the possibility of there not being a path at all, but at least what you've showed me is a solid start. Many thanks for that! :slight_smile:

Try dirname

If I'm honest: Didn't think of that.
I _always_ use absolute pathnames, that's why :slight_smile:

You could do some basic checks on $1.

Something like this maybe (one line):
[[ ! -n $1 ]] || [[ $1 == "/" ]]&& echo "Supply (correct) filename please." && exit 1

If $1 is NULL OR $1 equals / then print the message and exit.

Man, that felt a little bit like what must have felt to find out about wget :wink:

Seriously, now. Perderabo: you rock.
And that's not to forget or diminish your input, druuna -- thanks to both!

This is what I made out of this:

#!/bin/sh  
echo "original : "$1      
echo ""
filenameonly=`basename $1`    
echo "file name only : "$filenameonly
echo ""
pathonly=`dirname $1`"/"   
echo "path only : "$pathonly

and as you can see:

DigitalGoddess:~/bin ropers$ ./cut-it /mus/tard
original : /mus/tard

file name only : tard

path only : /mus/

it absolutely cuts the mustard. :slight_smile:

PS:
That't probably the "worst" thing about UNIX: It's too powerful and too diverse. No matter whether you know little or lots -- you're bound to run across a situation where you write a fantastic piece of code to handle a certain task -- only to find out later that, well, someone else had that problem before and s/he coded a solution which may or may not even be part of your default distribution. :slight_smile: But one can only learn along the way.

A nice and 'clean' sollution, like it better then mine :slight_smile:

That's one of the things I like about the whole *nix family: So many ways to do something and a few of those could be real beauties.

personaly i would use perls

File::Path or File::Find

Personally, I would have recommended dirname as Perderabo did! In any case, in keeping with the theme of this thread, here is my long winded version of grabbing an arguments path!! :wink:

#!/usr/bin/ksh
     
PARENT_PATH=$1
     
echo "Parent is $PARENT_PATH"
     
TEST=$(echo $PARENT_PATH | awk ' {
          arraySize = split($0, parentPath, "/");
          delete parentPath[arraySize];
    
           for (i in parentPath ) {
              path = path "/" parentPath;
              }
              print path;
              exit;
            }
             '
          )
echo "New Path Is: $TEST"

It is always better to use standard Unix commands when available...

dirname $Var
basename $Var