Bashで変数を使用してハードリンクを介してディレクトリを再帰的にコピーする方法は?

Bashで変数を使用してハードリンクを介してディレクトリを再帰的にコピーする方法は?

私が望むのは、ディレクトリ1を取得することです。

Dir1
    Dir A
        File A
    Dir B
        File B

次に、このfindコマンドを使用して、Dir 1の各ファイルに次のような既存のハードリンクがあることを確認します。

find . -type f -links 1 -exec cp -al {} /path/to/Dir2/{} \;

それから私は次のように終わりたいと思います:

Dir2
    Dir A
        File A (hardlink)
    Dir B
        File B (hardlink)

今、私はディレクトリ内のハードリンク以外のすべてのファイルを見つけ、そのファイルのハードリンクを別のディレクトリに配置する方法を知っていますが、新しいハードリンクを作成するときに同じディレクトリ構造を維持したいと思います。現在のコマンドは、次のような結果を生成します。

Dir2
    File A (hardlink)
    File B (hardlink)

ファイルBを見ていて、ファイルBにリンクが1つしかないと仮定すると(まだハードリンクされていない)、そのディレクトリを新しいディレクトリにコピーするために「Dir B」をどのように参照しますか?私は「/Path/To/Dir B」が単に「Dir B」になることを望んでいません。

Bashでこれを行う方法はありますか?

答え1

findなどのツールを使用してこれを行うことができます。mkdir

Bashファイルで、.sh/path/to/Dir1をソースディレクトリパスに置き換え、/path/to/Dir2をターゲットディレクトリパスに置き換えることを忘れないでください。

#!/bin/bash

src_dir="/path/to/Dir1"
dest_dir="/path/to/Dir2"

find "$src_dir" -type d -print0 | while IFS= read -r -d '' dir; do
    dest_subdir="${dir/$src_dir/$dest_dir}"
    
    mkdir -p "$dest_subdir"
    
    find "$dir" -maxdepth 1 -type f -links 1 -print0 | while IFS= read -r -d '' file; do
        cp -al "$file" "$dest_subdir"
    done
done

答え2

はい、変数を使用するように変更する代わりに、コマンドをrsync使用してbashでこれを実行できます。以下は、お客様の要件を満たす必要があるコマンドの例です。cpfind

#!/bin/bash
# Set source and destination directories
src_dir="Dir1"
dest_dir="Dir2"

# Use find to locate all files in source directory with only one link
find "$src_dir" -type f -links 1 | while read file; do
  # Get the directory name of the file and create the corresponding directory in the destination
  dir=$(dirname "$file")
  mkdir -p "$dest_dir/$dir"

  # Copy the file using rsync with the -l (hardlink) option
  rsync -av --link-dest="$src_dir" "$file" "$dest_dir/$file"
done

関連情報