私のハードドライブ上のファイルのフルパスのリストを含むテキストファイルがあります。数千行にすることができますが、以下は私の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}"
volume_content.txt
各行にはパターンがあるため、最終的には my の内容全体を収集しますTVC
。
grep
ソートを2回使用して正しい行を抽出しました。
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
これを達成する簡単な方法(おそらく1行)がありますか?
答え1
次の行が機能します。
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
のため外部すべてのルールブロックは「true」と評価されます)。
とにかく行全体を考慮するので、フィールド区切り文字に設定しても/
構文解析は妨げられません。footages.txt
最初のファイルを処理するのか、それとも後続のファイルを処理するのかという違いは、グローバルラインNR==FNR
カウンタをファイル固有のラインカウンタとNR
比較する条件によって決まりますFNR
。同じ場合、最初のファイルです。