[英]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
這里真的沒有必要使用sed
或awk
,只需使用我們的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.