在寻找成对的相同文件

时间:2015-02-07 09:48:00

标签: bash file nested-loops

我需要为具有相同标题(但不是扩展名!)的文件对寻找2个目录,并在一些新命令中合并它们的标题。

首先如何只打印文件名

1)通常我在for循环中使用以下命令来选择循环文件的全名

for file in ./files/* do;
 title=$(base name "file")
 print title
done

我应该在上面的脚本中更改哪些内容作为文件名称的标题而不是其扩展名?

2)如何添加一些条件来检查两个文件是否具有相同的名称,对它们执行双循环e,g

# counter for the detected equal files
i=0
for file in ./files1/* do;
 title=$(base name "file") #change it to avoid extension within the title
 for file2 in ./files2/* do;
 title2=$(basename "file2") #change it to avoid extension within the title2
 if title1==title2
 echo $title1 and $title2 'has been found!'
 i=i+1

完成

感谢您的帮助! 格列勃

1 个答案:

答案 0 :(得分:1)

您可以先修改脚本中的语法错误,例如do后跟;,反之亦然。

然后,shell有运算符从变量中的开头(###)和结束(%%%)中删除子字符串。以下是如何列出没有扩展名的文件,即从右侧删除与glob .*匹配的最短部分:

 for file in *; do
    printf '%s\n' "${file%.*}"
 done

阅读shell手册以了解这些操作符。它会在你的编程生涯中多次为自己付出代价: - )

不要相信有人告诉你使用丑陋且昂贵的管道并使用basename,cut,awk等分叉。这太过分了。

另一方面,也许有更好的方法来实现你的目标。假设你有这样的文件:

$ find files1 files2
files1
files1/file1.x
files1/file3.z
files1/file2.y
files2
files2/file1.x
files2/file4.b
files2/file3.a

现在创建两个文件名列表,剥离扩展名:

ls files1 | sed -e 's/\.[^.]*$//' | sort > f1
ls files2 | sed -e 's/\.[^.]*$//' | sort > f2

comm实用程序测试两个文件中常见的行:

 $ comm f1 f2
                file1
 file2
                file3
        file4

第一列仅在f1中列出行,第二列仅在f2中列出第二列,第三列在两者中共有。使用-1 -2 -3选项可以抑制不需要的列。如果您只需要计算公共文件(第三列),请运行

$ comm -1 -2 f1 f2 | wc -l
      2