Awk 如何在两个不同的目录中区分不同的文件,并将不同的文件存储在一个新目录中

Awk 如何在两个不同的目录中区分不同的文件,并将不同的文件存储在一个新目录中,awk,sed,diff,Awk,Sed,Diff,我有两个目录,dir1和dir2,其中分别有m和n个文件。条件可以是m>n或m 我想区分两个目录中的文件,并将不同的文件存储在一个新目录diffdir中 因此diffdir应该只有在两个dir中不同的文件 我曾经 diff -r dir1 dir2 | grep dir2 它提供了两个目录中不同的文件 diff -r dir1/DISP.case_sc.in.XXX dir2/**DISP.case_sc.in.XXX** 其中XXX可能在001到999之间变化(我在这里手动添加了**以使

我有两个目录,dir1和dir2,其中分别有m和n个文件。条件可以是m>n或m 我想区分两个目录中的文件,并将不同的文件存储在一个新目录diffdir中

因此diffdir应该只有在两个dir中不同的文件

我曾经

diff -r dir1 dir2 |  grep dir2
它提供了两个目录中不同的文件

diff -r dir1/DISP.case_sc.in.XXX dir2/**DISP.case_sc.in.XXX**
其中XXX可能在001到999之间变化(我在这里手动添加了**以使名称加粗)。 我只需要diffdir中的文件(粗体)

由于两个目录中的文件数量不同,因此在m>n的情况下,它也会给出上述命令的输出(diff-r dir1 dir2 | grep dir2)

我还需要diffdir中的DISP.case\u sc.in.YYY文件。这里YYY是等于差值m-n的文件数。例如,如果m=020和n=010,则此YYY将在011到020之间变化

在这两个dir(1和2)中,有些文件与未使用diff命令打印的文件完全相同,我需要这些文件位于另一个名为nodiffdir的目录中

带有文件名的示例输入,以指示它们之间的关系:

dir1
    dir1_only
    comm_diff
    comm_same

dir2
    dir2_only
    comm_diff
    comm_same
预期输出(dir1和dir2保持不变):

$awk'FNR==1{print ORS FILENAME}1'samedir/*diffdir/*
相同/通信相同
B
diffdir/comm_diff
1c1
d
仅diffdir/dir1_
A.
仅diffdir/dir2_
A.
这可能适合您(GNU-sed):

创建一个新目录
dir3

区分两个目录
dir1
dir2
,并通过管道将输出传输到sed调用

将包含
dir2
的每一行转换为复制命令

如果输出与预期相符,则通过添加
e
命令进行实际复制:

mkdir dir3
diff -r dir1 dir2 |
sed '/dir2/!d;s#: #/#;s/.* //;s/.*/cp & &/;s/dir2/dir3/2;e'

这对我很有效,但我还需要在另一个目录“nodifdir”中的两个目录中没有任何差异的文件。对于包含
dir2
(例如
foodir2bar
)的文件名,这将失败或空格或
s,或以减号开头,或包含通配符或其他不太明显的情况。不客气,对于下一个问题,只需提供一个简洁、可测试的示例输入和预期输出,事情就会简单得多。好的,我将遵循这一点。能否扩展此脚本,使其删除以samedir格式dir1复制的文件?因为samedir中的文件在dir1中也将相同,我想将它们从dir1中删除。只需在
cp--“$f1”samedir
中将
cp
(用于“复制”)更改为
mv
(用于“移动”)。
samedir
    comm_same   # copied as-is from dir1 or dir2

diffdir
    comm_diff   # output of "diff dir1/comm_diff dir2/comm_diff"
    dir1_only   # copied as-is from dir1
    dir2_only   # copied as-is from dir2
$ cat tst.sh
#!/usr/bin/env bash

mkdir -p samedir &&
cp -r dir1 diffdir &&
cp dir2/* diffdir &&
for f1 in dir1/*; do
    fname="${f1##*/}"
    f2="dir2/${fname}"
    if [ -f "$f2" ]; then
        if diff -- "$f1" "$f2" > "diffdir/${fname}"; then
            cp -- "$f1" samedir &&
            rm "diffdir/${fname}"
        fi
    fi
done
$ mkdir dir1
$ mkdir dir2
$ echo 'a' > dir1/dir1_only
$ echo 'a' > dir2/dir2_only
$ echo 'b' > dir1/comm_same
$ echo 'b' > dir2/comm_same
$ echo 'c' > dir1/comm_diff
$ echo 'd' > dir2/comm_diff
$ ls *
tst.sh

dir1:
comm_diff   comm_same   dir1_only

dir2:
comm_diff   comm_same   dir2_only
$ ./tst.sh
$ ls *
tst.sh

diffdir:
comm_diff   dir1_only   dir2_only

dir1:
comm_diff   comm_same   dir1_only

dir2:
comm_diff   comm_same   dir2_only

samedir:
comm_same
$ awk 'FNR==1{print ORS FILENAME} 1' samedir/* diffdir/*

samedir/comm_same
b

diffdir/comm_diff
1c1
< c
---
> d

diffdir/dir1_only
a

diffdir/dir2_only
a
mkdir dir3
diff -r dir1 dir2 |
sed '/dir2/!d;s#: #/#;s/.* //;s/.*/cp & &/;s/dir2/dir3/2'
mkdir dir3
diff -r dir1 dir2 |
sed '/dir2/!d;s#: #/#;s/.* //;s/.*/cp & &/;s/dir2/dir3/2;e'