Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to split path by last slash?

Tags:

bash

split

I have a file (say called list.txt) that contains relative paths to files, one path per line, i.e. something like this:

foo/bar/file1 foo/bar/baz/file2 goo/file3 

I need to write a bash script that processes one path at a time, splits it at the last slash and then launches another process feeding it the two pieces of the path as arguments. So far I have only the looping part:

for p in `cat list.txt` do    # split $p like "foo/bar/file1" into "foo/bar/" as part1 and "file1" as part2    inner_process.sh $part1 $part2 done 

How do I split? Will this work in the degenerate case where the path has no slashes?

like image 917
I Z Avatar asked Dec 07 '12 16:12

I Z


People also ask

How do you split paths?

The Split-Path cmdlet returns only the specified part of a path, such as the parent folder, a subfolder, or a file name. It can also get items that are referenced by the split path and tell whether the path is relative or absolute. You can use this cmdlet to get or submit only a selected part of a path.

How do I split a path in bash?

Just use path=${p%/*} and file=${p##*/} . Or use basename and dirname .

How do I split a path in Windows Python?

split() method in Python is used to Split the path name into a pair head and tail. Here, tail is the last path name component and head is everything leading up to that. In the above example 'file. txt' component of path name is tail and '/home/User/Desktop/' is head.


2 Answers

Use basename and dirname, that's all you need.

part1=$(dirname "$p") part2=$(basename "$p") 
like image 54
piokuc Avatar answered Sep 19 '22 16:09

piokuc


A proper 100% bash way and which is safe regarding filenames that have spaces or funny symbols (provided inner_process.sh handles them correctly, but that's another story):

while read -r p; do     [[ "$p" == */* ]] || p="./$p"     inner_process.sh "${p%/*}" "${p##*/}" done < list.txt 

and it doesn't fork dirname and basename (in subshells) for each file.

The line [[ "$p" == */* ]] || p="./$p" is here just in case $p doesn't contain any slash, then it prepends ./ to it.

See the Shell Parameter Expansion section in the Bash Reference Manual for more info on the % and ## symbols.

like image 26
gniourf_gniourf Avatar answered Sep 17 '22 16:09

gniourf_gniourf