paultop6
paultop6

Reputation: 3761

With sed or awk, how do I match from the end of the current line back to a specified character?

I have a list of file locations in a text file. For example:

/var/lib/mlocate

/var/lib/dpkg/info/mlocate.conffiles

/var/lib/dpkg/info/mlocate.list

/var/lib/dpkg/info/mlocate.md5sums

/var/lib/dpkg/info/mlocate.postinst

/var/lib/dpkg/info/mlocate.postrm

/var/lib/dpkg/info/mlocate.prerm

What I want to do is use sed or awk to read from the end of each line until the first forward slash (i.e., pick the actual file name from each file address).

I'm a bit shakey on syntax for both sed and awk. Can anyone help?

Upvotes: 2

Views: 3720

Answers (8)

13ren
13ren

Reputation: 12187

This is a less-clever, plodding version of gbacon's:

sed -e 's/^.*\/\([^\/]*\)$/\1/'

Upvotes: 0

Diego Torres Milano
Diego Torres Milano

Reputation: 69228

Thius would do the trick too if file contains the list of paths

 $ xargs -d '\n' -n 1 -a file basename

Upvotes: 0

ghostdog74
ghostdog74

Reputation: 342433

@OP, you can use awk

awk -F"/" 'NF{ print $NF }' file 

NF mean number of fields, $NF means get the value of last field

or with the shell

while read -r line
do
    line=${line##*/} # means longest match from the front till the "/" 
    [ ! -z  "$line" ] && echo $line
done <"file"

NB: if you have big files, use awk.

Upvotes: -1

marco
marco

Reputation: 4675

I am for "basename" too, but for the sake of completeness, here is an awk one-liner:

awk -F/ 'NF>0{print $NF}' <file.txt

Upvotes: 3

Dennis Williamson
Dennis Williamson

Reputation: 360143

Pure Bash:

while read -r line
do
    [[ ${#line} != 0 ]] && echo "${line##*/}"
done < files.txt

Edit: Excludes blank lines.

Upvotes: 1

Benjamin Bannier
Benjamin Bannier

Reputation: 58604

There's really no need to use sed or awk here, simply us basename

IFS=$'\n'
for file in $(cat filelist); do
   basename $file;
done

If you want the directory part instead use dirname.

Upvotes: 1

Greg Bacon
Greg Bacon

Reputation: 139521

$ sed -e 's!^.*/!!' locations.txt
mlocate
mlocate.conffiles
mlocate.list
mlocate.md5sums
mlocate.postinst
mlocate.postrm
mlocate.prerm

Regular-expression quantifiers are greedy, which means .* matches as much of the input as possible. Read a pattern of the form .*X as "the last X in the string." In this case, we're deleting everything up through the final / in each line.

I used bangs rather than the usual forward-slash delimiters to avoid a need for escaping the literal forward slash we want to match. Otherwise, an equivalent albeit less readable command is

$ sed -e 's/^.*\///' locations.txt

Upvotes: 5

sud03r
sud03r

Reputation: 19769

Use command basename

$~hawk] basename /var/lib/mlocate
mlocate

Upvotes: 5

Related Questions