简体   繁体   中英

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 (ie, pick the actual file name from each file address).

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

$ 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

Use command basename

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

我也是“basename”,但为了完整起见,这里有一个awk单行:

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

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 .

Pure Bash:

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

Edit: Excludes blank lines.

如果file包含路径列表,Thius也会这样做

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

这是gbacon的一个不太聪明,有点模糊的版本:

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

@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.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM