[英]How to extract substring from a text file in bash?
I have lots of strings in a text file, like this: "/home/mossen/Desktop/jeff's project/Results/FCCY.png" "/tmp/accept/FLWS14UU.png" "/home/tten/Desktop/.wordi/STSMLC.png"
我希望只使用bash shell腳本逐行讀取文本文件時從字符串中獲取文件名。 文件名將始終以.png結尾,並且前面總是有“/”。 我可以將每個字符串都變成var,但是將文件名(FCCY.png,FLWS14UU.png等)提取到變量中的最佳方法是什么? 我不能指望擁有Perl,Python等用戶,只需要標准的Unix工具,如awk和sed。
Thanks, mossen
你想要的基basename
:
$ basename /tmp/accept/FLWS14UU.png
FLWS14UU.png
basename一次只能處理一個文件/字符串。 如果你有很多字符串,你將迭代文件並多次調用外部命令。
使用awk
$ awk -F'[/"]' '{print $(NF-1)}' file
FCCY.png
FLWS14UU.png
STSMLC.png
或者使用shell
while read -r line
do
line=${line##*/}
echo "${line%\"}"
done <"file"
newlist=$(for file in ${list} ;do basename ${file}; done)
$ var="/home/mossen/Desktop/jeff's project/Results/FCCY.png"
$ file="${var##*/}"
迭代地使用basename會帶來巨大的性能損失。 當你在一兩個文件上做它時,它很小而且不明顯,但卻增加了數百個。 讓我為您做一些計時測試,以舉例說明為什么在內部功能可以完成工作時使用basneame(或任何系統util callout)是不好的 - Dennis和ghostdog74為您提供了更有經驗的BASH答案。
示例輸入files.txt(我的照片列表,包含完整路徑): 3749個條目
external.sh
while read -r line
do
line=`basename "${line}"`
echo "${line%\"}"
done < "files.txt"
internal.sh
while read -r line
do
line=${line##*/}
echo "${line%\"}"
done < "files.txt"
定時結果,將輸出重定向到/ dev / null以消除任何視頻延遲:
$ time sh external.sh 1>/dev/null
real 0m4.135s
user 0m1.142s
sys 0m2.308s
$ time sh internal.sh 1>/dev/null
real 0m0.413s
user 0m0.357s
sys 0m0.021s
兩者的輸出完全相同:
$ sh external.sh | sort > result1.txt
$ sh internal.sh | sort > result2.txt
$ diff -uN result1.txt result2.txt
因此,您可以從時序測試中看到,當您可以在某些創造性的BASH代碼/術語中編寫相同的功能以完成工作時,您確實希望避免對系統實用程序進行任何外部調用,尤其是當它將被稱為一大堆時一遍又一遍。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.