2

最初に、askubuntuで同じことを尋ねてみましたが、そこまでは行きません... https://askubuntu.com/questions/186114/how-to-diff-two-folders-to-multiple-patch-files/ 186121#コメント231985_186121

だから、ここにコピーして貼り付けて、SOが実用的な解決策を提供してくれることを願っています...

私は UNIX にあまり詳しくないので、次のように質問します。

次の問題があります-たくさんのサブフォルダーを持つ2つのフォルダー。私はそれらを区別する必要があります。

私はこれを試しました:

diff -drupN vanila_kernel_3.0.8 my_kernel_3.0.8 > kernel.patch

その結果、185MBのファイルが生成されます...そして、私が本当に望んでいるものではありません。

diff の結果を多くの小さなパッチにする必要があります。理想的には、変更の内容を含む変更されたファイルごとに 1 つです。つまり、diff の使用方法を変更する必要があり、何らかのループに入れる必要があるということです。この小さなスクリプトを実行してみました。

for file in original_308/*.*; do
    diff -dupN "$file" "my_308/${file##*/}" > "$file".patch
done

しかし、うまくいきません:/

理想的には、変更ごとに .patch ファイルを作成したいのですが、オリジナルで変更されたファイルにパッチを適用しても問題ありません (新しく追加されたファイルをフィルター処理してコピーするだけでよいため)。

誰かがこれを行うためのまともな方法を私に提供できますか?

更新: これらのフォルダーと 4546 の新しく追加されたファイルの間に 231 個の変更されたファイルがあることを知っています...私はそれらの 231 個のパッチを生成することに興味があります。スクリプトでも使用できるように、これらの 231 個のファイル名を含むファイルもあります。

これを使用して変更ログを生成しました

diff -qdr -x *.o -x *.cmd -x *.d original_308 my_308 | sed "s/^.* and \(.*\) differ/\1/" | sort > changes.txt

そして、変更されたファイル名を出力し、「my_308のみ」ファイルが続きます... 231個のファイルがそのファイルの先頭にあります(最初の231行)

明確にしましょう。ソース ファイルには .patch ファイルが必要です。パッチが patchs//file_name.c.patch で終わることができれば、それは本当に素晴らしいことです...

もし私にPERLスクリプトをくれたら、私はそのゴミを理解していないので、それらを最もよく使う方法を教えてください. 私を失望させないでください。私はこれを移植し、テストし、実行する必要があり、UNIX コマンドと実体のないスクリプト ffs に時間を浪費しています。

4

5 に答える 5

2

このようなもの?

DIR1="vanila_kernel_3.0.8"
DIR2="my_kernel_3.0.8"
OUTDIR="patches"
SUFFIX=".patch"

while IFS="," read f1 f2; do
  filename=${f1#$DIR1}  # remove base dir name
  outfile="${OUTDIR}/${filename}${SUFFIX}"
  mkdir -p $(dirname $outfile)  # make sure output directory exist

  diff -dupN "$f1" "$f2" > "$outfile"
done < <(diff -qdr $DIR1 $DIR2 | awk '/differ$/{print $2","$4}')

簡単な説明:

diff -qdr $DIR1 $DIR2 | awk '/differ$/{print $2","$4}'

これにより、フォームで変更されたファイルのリストが表示されますsource_file,dest_file。これを に渡すと、while ...read..変更された各ファイルのループ本体が実行され、ファイル名はf1および f2 として保存されます。

filename=${f1#$DIR1}  # remove base dir name

これにより、(ベース ディレクトリを削除することにより) ファイル名の末尾部分が削除されるため、出力パッチ ファイルの適切なパスを特定できます。f1その後は、出力ディレクトリが存在することを確認し、差分結果をおよびに書き出すだけf2です。

すべてのファイル名を引用符で囲むことで、ファイル名のスペースを処理できるようになります。

于 2012-09-10T16:12:37.603 に答える
2

<Learning Perl> の本を手に取って、1 週間で学習できます。Perl はとてもクールです。ゴミと呼ばないでください。パッチを生成するためのシェルスクリプトは次のとおりです

find ./original_308 -type f | while read file
do
  nfile="./my_308/${file#*original_308/}"
  if [ -f $nfile ]; then
    patchfile="./patch/${file#*original_308/}.patch"
    mkdir -p `dirname $patchfile`
    echo "checking $file $nfile"
    diff -dupN "$file" "$nfile" > "$patchfile" && rm "$patchfile"
  fi
done

diff xxx >patch && rm patch は、空のパッチ ファイルのみを削除します。

于 2012-09-10T16:24:27.667 に答える
1

与えたオプションが上に示したものと異なっkernel.patchていても、これはファイルで機能するはずです。diff

perl -ne 'if(m{^diff .* (.*/.*) (.*/.*)}) {
              my $f = $1;
              $f =~ s{/}{_}g;
              open $FH, ">", "$f.patch" or die $!;
          } else {
              print {$FH} $_;
          }' kernel.patch

ファイル名にスペースが含まれていると、これが機能しなくなる可能性があります。

于 2012-09-10T15:37:59.610 に答える
1

皆さんの貢献に感謝します...これが最終結果です

#!/bin/bash                               
FOLDER_OLD="original"
FOLDER_NEW="changed"
FOLDER_PATCHES="./fresh_patches"

echo "Generating changelog for $FOLDER_OLD --> $FOLDER_NEW"
diff -qdr ${FOLDER_OLD} ${FOLDER_NEW} | sed "s/^.* and \(.*\) differ/\1/" | sort > newchanges.txt

mkdir -p ${FOLDER_PATCHES}                                                                                                           
for newfile in `find $FOLDER_NEW -type f`
do
sufix=${newfile#${FOLDER_NEW}/}
oldfile="${FOLDER_OLD}/${sufix}"

if [ -f $oldfile ]; then
    patchfile="${FOLDER_PATCHES}/`echo $sufix |sed 's/\//_/g'`.patch"
    if [ "`diff $oldfile $newfile`" != "" ]; then
        echo "Make patch ${patchfile}"
        diff -dupN "$oldfile" "$newfile" > "$patchfile"
    fi
else
patchfile="${FOLDER_PATCHES}/ADDONS/${newfile#$FOLDER_NEW}"
    echo "Copy $newfile --> $patchfile"
    mkdir -p "`dirname ${patchfile}`"
    cp $newfile $patchfile
fi
done

スクリプトは最初に、変更されたファイルと新しいプロジェクト/フォルダーにのみ固有のファイルのリストを生成します。次に、すべてのファイルのパッチ ファイルを生成し、新しく追加されたファイルを ADDONS フォルダー (新しいプロジェクトに固有) にコピーします。

于 2012-09-12T16:05:20.767 に答える