Faj*_*ond 3 bash text-processing macos
我有一个文本文件,其中包含来自硬盘驱动器的文件的完整路径列表。这可以是千行,但这里是我的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
Run Code Online (Sandbox Code Playgroud)
假设我在里面有搜索关键字footages.txt
,但这些关键字应该只指文件名:
A002
TVC
Run Code Online (Sandbox Code Playgroud)
如果我使用
footage=$(cat footages.txt)
cat volume_content.txt | grep "${footage}"
Run Code Online (Sandbox Code Playgroud)
它最终会收集 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
Run Code Online (Sandbox Code Playgroud)
这就是结果,这就是我想要的:
/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
Run Code Online (Sandbox Code Playgroud)
有没有简单的方法(可能是一个班轮)来实现这一目标?
以下单行应该工作:
awk -F'/' 'NR==FNR {pat=pat ? pat "|" $0 : $0; next} $NF ~ pat' footages.txt volume_content.txt
Run Code Online (Sandbox Code Playgroud)
这首先处理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
因为无论如何我们只考虑整行。
我们是处理第一个文件还是任何后续文件的区别是通过 condition NR==FNR
,它将全局行计数器NR
与每个文件的行计数器进行比较FNR
。如果它们相等,则它是第一个文件。