如何使用Awk遍历两个目录并匹配同名文件前缀输出指定内容?
用Awk实现匹配文件前缀并输出指定格式
环境与文件结构
我在/home/目录下有两个文件夹:dirA和dirB。
- dirA下的文件:
fileA.txt fileB.txt fileC.txt - dirB下的文件:
fileA.yaml fileB.yaml fileC.yaml
期望目标
通过Awk的-F选项,分别以.txt和.yaml作为分隔符提取文件名的前缀部分($1),当两个目录下的文件名前缀匹配时,输出如下格式内容:
dirA_files fileA == dirB_files fileA dirA_files fileB == dirB_files fileB dirA_files fileC == dirB_files fileC
补充:前缀不匹配的情况无需输出任何内容。
当前已有Bash实现思路
当前工作路径为/home/,我已经写出了Bash的实现代码,但想知道是否可以用Awk完成该需求:
while read -r dirA_files do while read -r dirB_files do if [ "$dirA_files" == "$dirB_files" ] then echo "dirA_files $dirB_files == dirB_files $dirB_files" done < <(find dirA -name '*.txt' -ls | awk '{print $11}' | sed -e 's|dirA/||g' | awk -F '.txt' '{print $1}') done < <(find dirB -name '*.yaml' -ls | awk '{print $11}' | sed -e 's|dirB/||g' | awk -F '.yaml' '{print $1}')
Awk实现方案
完全可以用Awk完成这个需求,且逻辑更简洁高效,无需嵌套循环。下面提供几种不同场景下的实现方式:
方法一:结合ls与Awk(适合文件名无特殊字符的场景)
ls dirA/*.txt | awk -F'[/.]' '{arr[$2]++}' && ls dirB/*.yaml | awk -F'[/.]' '$2 in arr {print "dirA_files", $2, "==", "dirB_files", $2}'
- 逻辑说明:
- 第一部分提取dirA下txt文件的前缀(以
/和.为分隔符,取$2),存入数组arr。 - 第二部分提取dirB下yaml文件的前缀,检查是否在数组中,存在则按指定格式输出。
- 第一部分提取dirA下txt文件的前缀(以
方法二:用find配合Awk(兼容含特殊字符的文件名)
如果文件名包含空格等特殊字符,用ls容易出问题,改用find更稳妥:
find dirA -maxdepth 1 -type f -name "*.txt" | awk -F'[/.]' '{arr[$2]++}' && find dirB -maxdepth 1 -type f -name "*.yaml" | awk -F'[/.]' '$2 in arr {printf "dirA_files %s == dirB_files %s\n", $2, $2}'
- 逻辑说明:
-maxdepth 1限制只查找当前目录的文件,不递归子目录。- 同样通过分隔符提取前缀,利用数组存储匹配项,最后输出符合条件的内容。
方法三:单Awk进程完成(高效合并处理)
可以把两个目录的文件输出合并后传给Awk,一次完成处理:
{ find dirA -maxdepth 1 -type f -name "*.txt"; find dirB -maxdepth 1 -type f -name "*.yaml"; } | awk -F'[/.]' ' $3 == "txt" { arr[$2]++ } $3 == "yaml" && $2 in arr { print "dirA_files", $2, "==", "dirB_files", $2 } '
- 逻辑说明:
- 合并两个
find的输出传给Awk。 - 对txt文件,将前缀存入数组;对yaml文件,检查前缀是否在数组中,符合条件则输出指定格式。
- 合并两个
内容的提问来源于stack exchange,提问作者Saeed
相关产品推荐
相关产品推荐

