我有一个文本文件,其中包含硬盘驱动器中文件的完整路径列表。这可能是数千行,但这里是我的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
有没有简单的方法(可能是一行)来实现这一点?
答案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
。如果相等,则为第一个文件。