ape*_*ace 2 linux bash comparison diff list
我想知道如何仅通过文件名(忽略扩展名)来比较两个目录(不递归)以获得差异.例如,如果我有列表A和B,我想知道A中存在什么而不是B.
我目前正在处理一些图像.在一个目录中,我有扩展名为.tiff的源文件,在另一个目录中,我处理了扩展名为.png的文件.两个目录中的文件名相同,但只有扩展名不同(例如,一个文件在目录A中命名为foo.tiff,在目录B中命名为foo.png).
我正在尝试查找尚未处理的文件.
谢谢!
首先让我们创建一个辅助函数:
getfiles() { find "$1" -maxdepth 1 -type f -exec bash -c 'for f in "$@"; do basename "${f%.*}"; done' "" {} + | sort; }
Run Code Online (Sandbox Code Playgroud)
如果运行getfiles dirname,它将返回该目录中的文件的排序列表,而不包含目录的名称且没有任何扩展名.该-maxdepth 1选项意味着find不会递归搜索.
现在,让我们比较文件目录A和B:
diff <(getfiles A) <(getfiles B)
Run Code Online (Sandbox Code Playgroud)
输出采用通常的diff格式.由于可以使用任何diff的常规选项,因此输出格式非常灵活.
这里是一个样本目录A和B,各自具有一个文件,其他不具备:
$ ls */
A/:
bar.png foo.png qux.png
B/:
bar.tiff baz.tiff foo.tiff
Run Code Online (Sandbox Code Playgroud)
输出:
$ diff <(getfiles A) <(getfiles B)
1a2
> baz
3d3
< qux
Run Code Online (Sandbox Code Playgroud)
输出正确地标识(a)B具有baz不存在的文件A和(b)A具有qux不存在的文件B.
假设我们只是想进行片面比较并找到哪些文件B也不在A.在这种情况下,grep可以使用:
$ grep -vxFf <(getfiles A) <(getfiles B)
baz
Run Code Online (Sandbox Code Playgroud)
这里使用的选项是:
-v告诉grep我们排除匹配的行
-x告诉我grep只匹配整行
-F告诉grep我们模式是固定的字符串,而不是正则表达式.
-f告诉grep从文件中获取模式列表,或者在这种情况下,获取类似文件的对象<(getfiles A).考虑这些文件:
$ ls */
A A/:
1 bar.png 1 foo.png 1 qux.png
B B/:
1 bar.tiff 1 baz.tiff 1 foo.tiff
Run Code Online (Sandbox Code Playgroud)
输出:
$ diff <(getfiles 'A A') <(getfiles 'B B')
1a2
> 1 baz
3d3
< 1 qux
Run Code Online (Sandbox Code Playgroud)
要么,
$ grep -vxFf <(getfiles 'A A') <(getfiles 'B B')
1 baz
Run Code Online (Sandbox Code Playgroud)
如果您的任何文件名中包含换行符,则会产生不正确的结果.至少对于grep表格,这可以扩展到更一般的情况.
如果我理解正确,您需要执行以下脚本:
#/bin/bash
SAVEIFS=$IFS
IFS=$(echo -en "\n\b")
folder1="/home/vagrant/1 b"
folder2="/home/vagrant/2 a"
ext1="tiff"
ext2="png"
for fullfile in ${folder1}/*.$ext1
do
#echo "$fullfile fullfile"
filename=$(basename "$fullfile")
#echo "$filename file"
extension="${filename##*.}"
#echo "$extension ext"
cleanfilename="${filename%.*}"
#echo "$cleanfilename base"
if ! [ -a "${folder2}/$cleanfilename.$ext2" ]
then
echo $fullfile
fi
done
IFS=$SAVEIFS
Run Code Online (Sandbox Code Playgroud)
它显示第一个文件夹中存在但第二个文件夹中不存在的文件。像这样:
admin$ mkdir 1
admin$ mkdir 2
admin$ touch 1/1.tiff
admin$ touch 1/2.tiff
admin$ touch 1/3.tiff
admin$ touch 2/1.png
admin$ touch 2/2.png
admin$ vim diff.sh
admin$ chmod +x diff.sh
admin$ ./diff.sh
/Users/admin/1/3.tiff
Run Code Online (Sandbox Code Playgroud)