find
コマンドを実行して、検索された複数の書籍へのシンボリックリンクを作成したいと思います。
まず、JSの本をすべて集めました。
find ~ -type f -iregex '.*javascript.*\.pdf' > js_books.md 2>/dev/null
35巻返却
../Coding/Books/HTML_Collections/Freeman E.T., Robson E. - Head First HTML5. Programming Building Web Apps with JavaScript - 2011.pdf
../Coding/Books/HTML_Collections/Learning Web Design - A Beginner's Guide to HTML, CSS, JavaScript, and Web Graphics - Jennifer Niederst Robbins - 4th Edition - August 2012.pdf
..
また、js_booksディレクトリにコピーしてください。
mkdir js_books
find ~ -type f -iregex '.*javascript.*\.pdf' -print0 -exec cp '{}' js_books
動作しますが、複数のコピーが大量のディスク領域を消費します。
だから私は本を削除し、その中にシンボリックリンクを作成しようとしました。
find ~ -type f -iregex '.*javascript.*\.pdf' -print0 -exec ln -s '{}' js_books/'{}' \;
js_booksディレクトリには何も返されません。
そのような問題を解決する方法は?
答え1
式はfind
非常に簡単で、bashシェルワイルドカードを使用して再現できます。
shopt -s globstar nocaseglob
for book in $HOME/Coding/**/*javascript*.pdf
do
ln -s "$book" "js_books/$(basename "$book")"
done
まず、bashに大文字と小文字を区別しないファイル名のグロービングを有効にし、サブディレクトリを介して再帰できるように指示し、次に「**
(any)javascript(any)pdf」パターンに一致するすべてのファイル名を繰り返します。各ファイル名に対して js_books へのシンボリックリンクを作成します。
各ファイル名の先頭を省略したため、有効なシンボリックリンクを作成する(またはシンボリックリンクターゲットで適切な数のプレフィックスを使用するには)、コマンドのループへのフルパスをfor
提供する必要があることに気づきました。別の起動ディレクトリを使用している場合に備えて、ディレクトリをに変更しました。ln
../
find ~
$HOME/Coding
答え2
目標js_books/'{}'
はjs_books
。ディレクトリの場合なぜなら元のファイルと同じ名前を使用してください。
ここでの問題は、{}が親ディレクトリ名を追加して機能を損なう可能性が最も高いことです。
答え3
1つの方法は、次のことです。
find ~ -type f -iregex '.*javascript.*\.pdf' -printf %f"*"%h | awk -F* '{ system("ln -s "$2"/"$1" "$2"/js_books/"$1) }'
findコマンドを実行し、ファイル名、アスタリスク、ディレクトリパスを順番に印刷します。 awkを介して実行し、ファイル名とディレクトリを分離し、awkのシステム機能を使用して実行されるlnコマンドを構築します。
これはコマンドの注入を可能にし、システムを使用して最終コマンドを実行する前に印刷を使用してコマンドを画面に印刷することもできます。