Bash

提取具有匹配文件名的完整路徑

  • September 22, 2020

我有一個文本文件,其中包含來自硬碟的文件的完整路徑列表。這可能是一千行,但這裡是我的volume_content.txt文件的範例:

/Volumes/NEW TVC/20200901/CAM_A/VID_A002C001.mov
/Volumes/NEW TVC/20200901/CAM_A/VID_A002C003.mov
/Volumes/NEW TVC/20200901/CAM_A/VID_A003C003.mov
/Volumes/NEW TVC/20200901/CAM_B/CARD01/20200905/TVC.mov

假設我在裡面有搜尋關鍵字footages.txt,但這些關鍵字應該只引用文件名:

A002
TVC

如果我使用

footage=$(cat footages.txt)
cat volume_content.txt | grep "${footage}"

它將最終收集 my 的全部內容volume_content.txt,因為每一行都有圖案TVC

我已經設法提取正確的行,通過使用grep兩次排序,使用:

footage=$(cat footages.txt)
cat volume_content.txt | sed 's!.*/!!' | grep "${footage}" > footage_filename.txt
footage_filename=$(cat footage_filename.txt)
cat volume_content.txt | grep "${footage_filename}" > all_footages.txt

這就是結果,這就是我想要的:

/Volumes/NEW TVC/20200901/CAM_A/VID_A002C001.mov
/Volumes/NEW TVC/20200901/CAM_A/VID_A002C003.mov
/Volumes/NEW TVC/20200901/CAM_B/CARD01/20200905/TVC.mov

有沒有簡單的方法(可能是一個班輪)來實現這一目標?

以下單行應該工作:

awk -F'/' 'NR==FNR {pat=pat ? pat "|" $0 : $0; next} $NF ~ pat' footages.txt volume_content.txt 

這首先處理footages.txt並生成一個正則表達式,該表達式由從每一行讀取的 ORed 單個模式組成。這個正則表達式儲存在一個內部變數中pat,看起來像A002|TVC你的例子。有點神秘的pat=pat ? pat "|" $0 : $0意思是“如果pat已經使用,設置pat=pat "|" $0,否則設置pat=$0”。請注意footages.txt,如果其中的模式本身就是實際的正則表達式,則需要付出更多的努力!

處理時volume_content.txt,它在 處拆分每一行,/並檢查最後一個路徑組件是否與先前組裝的正則表達式匹配pat。如果是這樣,則列印該行(因為$NF ~ pat放置任何規則塊之外的條件評估為“真”)。

設置/為欄位分隔符不會干擾解析footages.txt,因為無論如何我們只考慮整行。

我們是處理第一個文件還是處理任何後續文件之間的區別在於條件NR==FNR,它將全域行計數器NR與每個文件的行計數器進行比較FNR。如果它們相等,則它是第一個文件。

引用自:https://unix.stackexchange.com/questions/610711