我在两个不同的目录中有两个csv文件,我正在它们上运行一个diff,如下所示:
diff -b -r -w <dir-one>/AFB.csv <dir-two>/AFB.csv
我得到了预期的输出:
14c14
< image_collapse,,collapse,,,,,batchcriteria^M
---
> image_collapse1,,collapse1,,,,,batchcriteria^M
16a17
> image_refresh,,refresh,,,,,batchcriteria^M
我的要求是,已更改的行应转到changed.log文件,已附加的行应转至append.log。
输出清楚地表明,14c14中的"c"表示行发生了变化,16a17中的"a"表示行被追加。但是我如何将它们记录在不同的日志文件中。
编辑:与下面的原始答案相同,但避免了HP-UX上diff不支持的选项。使用类似的东西
diff -b -r -w /tmp/one.txt /tmp/two.txt
| sed -n -e '/c/ {s/[^c]*c(.*)/1 p/;p}'
| sed -n -f - /tmp/two.txt > /tmp/changed.txt
diff -b -r -w /tmp/one.txt /tmp/two.txt
| sed -n -e '/a/ {s/[^a]*a(.*)/1 p/;p}'
| sed -n -f - /tmp/two.txt > /tmp/new.txt
这将从diff
输出的行号转换为用于添加(a
)和更改(c
)行范围的sed
打印(p
)命令。将得到的sed
脚本应用于第二个文件,以仅打印所需的行。(我希望HP-UXsed
支持-f -
从标准输入中获取脚本。)
似乎有一种解决方案不需要解释diff
输出的行号。diff
支持--side-by-side
格式化(-y
),其中包括分别用<
、>
和|
标记旧行、新行和更改行的槽。您可以使用--width=1
(或-W1
)将这种并排格式简化为仅标记。如果使用更改的和新的标记(grep -v
)并在第二个文件的行中加上前缀(paste
),则可以通过加前缀的标记过滤(grep
)并丢弃(cut
)标记。您可以对新文件和更改的文件执行此操作。
以下是一个自包含的"脚本"示例:
# create two example files (one character per line)
echo abcdefghijklmnopqrstuvwxyz | grep -o . > /tmp/one.txt
echo abcDeFghiJKlmnopPqrsStuvVVwxyzZZZ | grep -o . > /tmp/two.txt
# diff side-by-side to get markers and apply to new file
diff -b -r -w -y -W1 /tmp/one.txt /tmp/two.txt
| fgrep -v '<' | paste - /tmp/two.txt
| grep -e '^|' | cut -c3- > /tmp/changed.txt
diff -b -r -w -y -W1 /tmp/one.txt /tmp/two.txt
| fgrep -v '<' | paste - /tmp/two.txt
| grep -e '^>' | cut -c3- > /tmp/new.txt
# dump result
cat /tmp/changed.txt
echo ---
cat /tmp/new.txt
其输出为
D
F
J
K
---
P
S
V
V
Z
Z
Z
我希望这能帮助你解决问题。
这可以通过如下的"grep"命令来完成。
diff -b -r -w <dir-one>/AFB.csv <dir-two>/AFB.csv | grep ">" >> append.log
diff -b -r -w <dir-one>/AFB.csv <dir-two>/AFB.csv | grep "<" >> changed.log