ディレクトリ構造を維持しながら複数のシンボリックリンクを生成する

ディレクトリ構造を維持しながら複数のシンボリックリンクを生成する

ディレクトリ構造を維持しながら、複数のフォルダからシンボリックリンクを作成したいと思います。いくつかの答えを読んで、今私が考えることができる最善の答えは次のとおりです。

find /data/DIV5/SASC/e042_ctcl/input/*/Clean_data/*/*/*.fq.gz -type f -exec ln -sf \{\} . \;

これにより、同じディレクトリにすべてのシンボリックリンクが生成されます。しかし、私が望むのは、findコマンドと同じディレクトリ構造を持ち、可能であれば入力と同じ構造を使用することです。たとえば、input/*/Clean_data/*/*/*.fq.gz

ファイルとディレクトリが一致する場合、シンボリックリンクはコマンドを使用して見つけた絶対リンクと同じ構造に従う必要がありますfind

どんな意見でも感謝します。

答え1

見苦しくて脆弱ですが、作業を完了する必要があります。

find /data/DIV5/SASC/e042_ctcl/input/*/Clean_data/*/*/*.fq.gz -type f -print0 | \
  xargs -0 -n 1 \
    sh -c 'mkdir -p "$PWD/`dirname $0`"; ln -s "$0" "$PWD/`dirname $0`"'

からインスピレーションを受けるカオスの回答、私はこの代替案を思いついたが、それも不要なディレクトリの整理:

find /data/DIV5/SASC/e042_ctcl/input/*/Clean_data/*/*/*.fq.gz -type f   \
     -printf 'mkdir -p "${PWD}/%h"; ln -s "%p" \\\n\t"${PWD}/%h"\n'   | \
sed 's#/data/DIV5/SASC/e042_ctcl##'                                   | \
sh -

それは必要なものを生成します目次そしてなぜなら注文する:

mkdir -p "${PWD}//data/DIV5/SASC/e042_ctcl/input/x/Clean_data/0/a"; ln -s "/data/DIV5/SASC/e042_ctcl/input/x/Clean_data/0/a/foobar.fq.gz" \
    "${PWD}//data/DIV5/SASC/e042_ctcl/input/x/Clean_data/0/a"

その後、不要なディレクトリを削除します。sed、次に続く。

mkdir -p "${PWD}//input/x/Clean_data/0/a"; ln -s "/data/DIV5/SASC/e042_ctcl/input/x/Clean_data/0/a/foobar.fq.gz" \
    "${PWD}//input/x/Clean_data/0/a"

これなぜならコマンドは同じ行から始まります。目次ターゲットの切り捨て中にソースをそのまま残すには、次の行に進みます。同じ行に印刷するか、別の行に印刷するには、より洗練された作業が必要です。sedスクリプト。

説明は次のとおりです。文書~のため探す、パラメータ-printf

%p ファイル名(絶対パス名ではなくfindで見つかったファイル名、つまり始点の1つの相対パス)。

%h ファイル名の前のディレクトリ(最後の要素と前のスラッシュを除くすべての要素)ファイル名にスラッシュが含まれていない場合(たとえば、コマンドラインで名前が指定されていて現在の作業ディレクトリにあるため)、 "%h"は "。 」に拡張されます。これにより、 "%h/%f" が "/foo" に拡張されるのを防ぐことができます。

答え2

awkコマンドを生成したら、次にパイプする必要がありますbash

find /data/DIV5/SASC/e042_ctcl/input/*/Clean_data/*/*/*.fq.gz -type f | \
awk '{printf "mkdir -p `dirname %s`\nln -s %s ./%s \n", substr($0, 27), $0, substr($0, 27)}'

これにより、最初に制御してから最後にパイプするコマンドのリストが生成されますbash。完全なコマンドは次のとおりです。

find /data/DIV5/SASC/e042_ctcl/input/*/Clean_data/*/*/*.fq.gz -type f | \
awk '{printf "mkdir -p `dirname %s`\nln -s %s ./%s \n", substr($0, 27), $0, substr($0, 27)}' | bash

答え3

私の印象は、あなたがこのようなツールを探しているということですGNUストー

GNU Stowは、ファイルシステムの異なるディレクトリにあるさまざまなソフトウェアおよび/またはパッケージをインポートし、同じ場所にインストールされているように見せるシンボリックリンクファームマネージャです。たとえば、/usr/local/binetcのファイルへのシンボリックリンクを含めることができ/usr/local/stow/emacs/bin、同様に他のサブ/usr/local/stow/perl/binディレクトリを再帰的に含めることもできます.../share.../man

ユースケースと一致していることを確認してください。

答え4

zshには便利な機能がありますzmv。最初にロードします(.zshrc単一セッションを使用するためにコマンドラインまたはコマンドラインでこれを実行できます)。

autoload -U zmv
alias zcp='zmv -C'
alias zln='zmv -L'

シンボリックリンクフォレストを再作成する方法は、次のように簡単です。

 zln -s '/data/DIV5/SASC/e042_ctcl/(input/*/Clean_data/*/*/*.fq.gz)' '$1'

Clean_data2レベルの深さではなくディレクトリを再帰的に探索したい場合:

 zln -s '/data/DIV5/SASC/e042_ctcl/(input/*/Clean_data/**/*.fq.gz)' '$1'

1つの大きな制限があります。これは、必要なサブディレクトリを作成しないことです。必要に応じてディレクトリを作成するためにラッパー関数を定義して使用lnします。

ln_s_mkdir () {
  mkdir -p -- ${(P)#}
  ln -s "$@"
}
 zmv -p ln_s_mkdir '/data/DIV5/SASC/e042_ctcl/(input/*/Clean_data/**/*.fq.gz)' '$1'

zshを使用してコマンドをより高速に実行できます。内部mkdirlnコマンド(ほとんどのシステムにあるGNUユーティリティよりもオプションが少ないため、デフォルトではロードされません。)

zmodload -F zsh/files b:zf_ln b:zf_mkdir
ln_s_mkdir () {
  zf_mkdir -p -- ${(P)#}
  zf_ln -s "$@"
}
 zmv -p ln_s_mkdir '/data/DIV5/SASC/e042_ctcl/(input/*/Clean_data/**/*.fq.gz)' '$1'

関連情報