簡體   English   中英

使用sed或awk,如何從當前行的末尾匹配回指定的字符?

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

我在文本文件中有一個文件位置列表。 例如:

/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

我想要做的是使用sed或awk從每行的末尾讀取,直到第一個正斜杠(即,從每個文件地址中選擇實際的文件名)。

我對sed和awk的語法都有些不滿。 有人可以幫忙嗎?

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

正則表達式量詞是貪婪的,這意味着.*匹配盡可能多的輸入。 讀取表單的模式.*X為“字符串中的最后一個X ”。 在這種情況下,我們將刪除每行中的最終/所有內容。

我使用了劉海而不是通常的正斜杠分隔符,以避免需要轉義我們想要匹配的字面正斜杠。 否則,雖然可讀性較低的命令是等效的

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

使用命令basename

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

我也是“basename”,但為了完整起見,這里有一個awk單行:

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

這里真的沒有必要使用sedawk ,只需使用我們的basename

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

如果您希望目錄部分改為使用dirname

Pure Bash:

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

編輯:排除空行。

如果file包含路徑列表,Thius也會這樣做

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

這是gbacon的一個不太聰明,有點模糊的版本:

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

@ OP,你可以使用awk

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

NF平均字段數,$ NF表示獲取最后一個字段的值

或與殼

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

注意:如果你有大文件,請使用awk。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM