求助:如何用AWK实现三类需复制文件的完整筛选逻辑?
使用AWK筛选需复制的文件(三类条件完整实现)
测试用CSV示例
source.csv(源文件列表)
"/path/to/source","file1.txt",1024,1690000000 "/path/to/source","file2.txt",2048,1691000000 "/path/to/source","file3.txt",512,1692000000 "/path/to/source","file4.txt",1536,1693000000
列定义:源目录路径、文件名、文件大小(字节)、Unix时间戳
target.csv(目标文件列表)
"/path/to/target","file1.txt",1024,1690000000 "/path/to/target","file2.txt",1024,1690000000 "/path/to/target","file3.txt",512,1691000000 "/path/to/target","file5.txt",2048,1690000000
列定义:目标目录路径、文件名、文件大小(字节)、Unix时间戳
预期输出(files_to_copy.txt)
file2.txt file3.txt file4.txt
三类条件的AWK实现方案
核心思路
先读取target.csv,把每个文件的大小和时间戳存储到关联数组中,键为去引号后的文件名;再遍历source.csv,逐一匹配三类条件,符合任一条件则输出文件名。
完整AWK命令
awk -v FS="," ' BEGIN { OFS = FS } # 处理target.csv,存储文件的大小和时间戳 FNR == NR { fname = $2 gsub(/"/, "", fname) size[fname] = $3 + 0 # 转为数值,避免引号干扰 mtime[fname] = $4 + 0 next } # 处理source.csv { fname = $2 gsub(/"/, "", fname) # 匹配三类条件 if ( !(fname in size) ) { # 条件1:目标中不存在该文件 print fname } else if ( ($3 + 0) != size[fname] ) { # 条件2:源与目标文件大小不同 print fname } else if ( ($4 + 0) > mtime[fname] ) { # 条件3:源文件时间戳晚于目标 print fname } } ' target.csv source.csv > files_to_copy.txt
命令关键细节解释
FNR == NR:仅处理第一个输入文件(target.csv),将文件元数据存入数组,确保后续对比有依据。gsub(/"/, "", fname):移除文件名中的双引号,避免字符串匹配时因引号导致的不匹配问题。$3 + 0/$4 + 0:将CSV中的字符串类型大小/时间戳转为数值,确保比较是数值运算而非字符串字典序比较。- 三个条件按顺序判断,覆盖所有需要复制的场景,无需额外调用
tr处理引号。
单独验证后两类条件(可选)
如果只想筛选目标已存在但需要更新的文件(仅条件2和3),可以使用以下命令:
awk -v FS="," ' BEGIN { OFS = FS } FNR == NR { fname = $2 gsub(/"/, "", fname) size[fname] = $3 + 0 mtime[fname] = $4 + 0 next } { fname = $2 gsub(/"/, "", fname) if ( fname in size ) { if ( ($3 + 0) != size[fname] || ($4 + 0) > mtime[fname] ) { print fname } } } ' target.csv source.csv > updated_files_to_copy.txt
该命令输出:file2.txt、file3.txt
内容的提问来源于stack exchange,提问作者cloudy
相关产品推荐
相关产品推荐

