簡體   English   中英

如何從bash中的文本文件中提取子字符串?

[英]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.

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