./ なしで検索結果を使用する

./ なしで検索結果を使用する

find を使用して多数のシンボリックリンクを作成しようとしていますが、{} を使用した結果を使用すると、各ファイル名の前に ./ が含まれます。これを回避するにはどうすればよいですか?

find . -type l -name '*.h' -exec ln -s /sourcedir/{} /destinationdir/{} \;

答え1

コマンド内の 1 文字だけを変更する必要があります。

find * -type l -name '*.h' -exec ln -s /sourcedir/{} /destinationdir/{} \;
#    ^

答え2

次のような標準構文を使用します。

S=/sourcedir D=/destdir find . -type l -name '*.h' -exec sh -c '
  for i do
    ln -s -- "$S${i#.}" "$D/$i"
  done' sh {} +

GNUisms を使用したい場合は、次のようにします。

find . -type l -name '*.h' -printf '/sourcedir/%P\0/destdir/%P\0' |
  xargs -r0n2 ln -s

あるいは、/sourcedir 現在のディレクトリ:

find "$PWD" -type l -name '*.h' -printf '%p\0/destdir/%P\0' |
  xargs -r0n2 ln -s

答え3

findは、引数として指定したパスを基準とした名前を出力します。この場合、パスは なので.、すべての名前は で始まります./。絶対パスを取得するには、入力として絶対パスを指定する必要があります。

find "$PWD" -type l -name '*.h'

このコマンドは$PWD、現在の作業ディレクトリの絶対パスを含む環境変数を使用するため、元のコマンドの意味が保持されます。

答え4

find . -type l -name '*.h' -print0 | cut -z -c3- \
    | xargs -0 -I '{}' ln -s '/sourcedir/{}' '/destinationdir/{}'

man find

  • -print0完全なファイル名とそれに続く文字を標準出力に出力しますnull

man cut- ファイルの各行からセクションを削除します

  • -z行区切り文字はNUL改行ではなく です。
  • -cこれらの文字のみを選択します。
  • N-1 から数えて N 番目のバイト、文字、またはフィールドから行末まで。

man xargs- 標準入力からコマンドラインを構築して実行します。

  • xargs [options] [command [initial-arguments]]
  • -0null入力項目は空白ではなく文字で終了し、引用符とバックスラッシュは特別なものではありません (すべての文字が文字通りに解釈されます)。
  • -I replace-strreplace-str内 の を標準入力から読み取った名前に置き換えますinitial-arguments。また、引用符で囲まれていない空白は入力項目を終了しません。代わりに、区切り文字は改行文字になります。 を意味します-L 1
  • -L max-linesmax-linesコマンドラインごとに 最大で空白以外の入力行を使用します。

関連情報