
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/{}'
-print0
完全なファイル名とそれに続く文字を標準出力に出力しますnull
。
man cut
- ファイルの各行からセクションを削除します
-z
行区切り文字はNUL
改行ではなく です。-c
これらの文字のみを選択します。N-
1 から数えて N 番目のバイト、文字、またはフィールドから行末まで。
man xargs
- 標準入力からコマンドラインを構築して実行します。
xargs [options] [command [initial-arguments]]
-0
null
入力項目は空白ではなく文字で終了し、引用符とバックスラッシュは特別なものではありません (すべての文字が文字通りに解釈されます)。-I replace-str
replace-str
内 の を標準入力から読み取った名前に置き換えますinitial-arguments
。また、引用符で囲まれていない空白は入力項目を終了しません。代わりに、区切り文字は改行文字になります。 を意味します-L 1
。-L max-lines
max-lines
コマンドラインごとに 最大で空白以外の入力行を使用します。