ソースとターゲットが似ている場合、bashでワイルドカード拡張を使用する最良の方法は何ですか?

ソースとターゲットが似ている場合、bashでワイルドカード拡張を使用する最良の方法は何ですか?

次のフォルダがあるとしましょう。

$ ls
css-tricks/ django-tutorial/ good-tuts.txt js-tut/ tutorials/ tuts.txt

それらのいくつかはtut彼らの名前にあります。tutその名前に含まれるすべてのファイル/フォルダをフォルダに移動したいと思いますtutorials/。私がコマンドを実行すると

$ mv *tut* tutorials/

次のメッセージを受け取りました。

mv: cannot move 'tutorials' to a subdirectory of itself, 'tutorials/tutorials'

これが起こらないようにするにはどうすればよいですか?


私が考えることができるトリックの1つは、ターゲットフォルダの名前を一時的に別の名前に変更し、コマンドが実行された後に再び目的の名前に変更することです。しかし、もっとエレガントな解決策を知りたいです。

答え1

個人的にインタラクティブにコマンドを実行しようとしている状況では、そうするとmv *tut* tutorials「移動できません」というエラーが発生することが予想されます。これは無害で、他のファイルやディレクトリは期待どおりに移動されます。

コマンドの終了ステータスはゼロではないためエラーを示しますが、コマンドに依存するものがないため無視できます。


この場合、他の名前の前にはダッシュが付きますtut

mv *-tut* tutorials

または、このような項目を移動するには、python_tut下線を使用できます。

mv *[_-]tut* tutorials

または、部分文字列の前に追加の文字を要求するにはtuttutorialsなし)

mv *?tut* tutorials

もう少し入力して考えてみると、次の拡張グローブパターンを使用できますbash

shopt -s extglob
mv *tut!(orials*) tutorials

tut2番目のバリアントは、直後に文字列が続かない部分文字列を含むすべての項目と一致しますorials。パターンが一致せずtutorialsスキップされますtutorials1

答え2

以下も使用できますfind

find . -type d -name "*tut*" -not -path "./tutorials" -exec mv -t "tutorials" {} +

答え3

次のメッセージを受け取りました。

mv: cannot move 'tutorials' to a subdirectory of itself, 'tutorials/tutorials'

エラーを無視してください。

完全なものではなく。グローバルパターンがターゲットと一致するため、エラーが発生することがわかります。また、システムはディレクトリを移動できないため、これは意味がないことを知っており、ファイルシステムが混乱する前にそれを実現するのに十分スマートです。

答え4

最も簡単な方法は、ターゲットディレクトリの名前をtutorials/ファイル名拡張子と一致しない別のディレクトリに変更し、移動を実行した後に目的の名前に変更することです。

関連情報