grep 後のディレクトリの移動

grep 後のディレクトリの移動

いくつかのディレクトリを「build_tools」フォルダに移動するために次のコマンドを発行しましたが、結果は期待したものではありませんでした。

ls -l | grep 2014-03 | awk '{if ($8!=build_tools) print $8}' | xargs mkdir build_tools/{} && mv {}/ build_tools/{}/

フォルダー「build_tools」を残りのディレクトリとともに awk (zlib) によって生成されたフォルダーの 1 つに移動しましたが、次のメッセージが表示されて停止しました。

mkdir: no se puede crear el directorio «zlib»: El archivo ya existe

誰か私の間違いが何なのか教えてくれませんか?

編集1:

ls -l の出力は次のようになります:

drwxr-xr-x  3 poissonbreaker poissonbreaker     4096 2011-05-02 09:58 antlr3.2
-rw-r--r--  1 poissonbreaker poissonbreaker   318588 2011-05-17 16:21 AppFramework-1.03.jar
-rw-r--r--  1 poissonbreaker poissonbreaker        0 2014-03-04 09:53 awk
drwxr-xr-x  4 poissonbreaker poissonbreaker     4096 2013-01-11 23:13 clutter-sharp
-rw-r--r--  1 poissonbreaker poissonbreaker      429 2014-01-14 09:49 Dependencias

日付フィールド ($6) が 2014-03 に一致するファイルを取得したいだけなので、次のように単純な grep を実行します (ディレクトリ内のファイルには、ファイル名としてこのパターンを持つものはありません)。

ls -l  | grep 2014-03 

その結果は次のようになります:

-rw-r--r--  1 poissonbreaker poissonbreaker        0 2014-03-04 09:53 awk
-rw-r--r--  1 poissonbreaker poissonbreaker      429 2014-01-14 09:49 Dependencias

次に、awk を介して各ファイルのファイル名フィールド ($8) を取得し、最終的に build_tools フォルダーに移動します (この時点で、何が間違いだったかがわかりました。build_tools フォルダーもこの日付に作成されています :S)。ただし、一部の部分が誰かの役に立つ可能性があるので、この質問をここに残しておきます。

編集2: awk 式を次のように変更しました。

awk '{if ($8!=build_tools) print $8}'

それが意味を成すように。

答え1

GNU をお持ちであると仮定しますfind。特定の期間内 (例: 2014 年 3 月) に変更されたファイルまたはディレクトリを移動する場合は、次のようにします。

find . -maxdepth 1 \
-newermt 2014-02-28 -not -newermt 2014-04-01 \
-not -name 'build_tools' \
-exec mv {} build_tools \+

説明:

  • サブディレクトリなしでこのディレクトリ内を検索
  • 2 月 28 日から 4 月 1 日までの範囲のファイルを検索します。ここで、mtは変更時刻を表します。 作成時刻を検索するためにも使用できますct
  • 名前が付けられていないbuild_tools
  • すべてを に移動しますbuild_tools。 は、\+見つかったすべてのファイル/ディレクトリ名が で 1 つずつ置換される{}のではなく、 で置換されることを意味します。 1 つずつ置換したい場合は、\;代わりに が必要です。

いくつかの点:

  • 出力を解析しないls形式はオペレーティング システムに依存しており、awkファイル名やディレクトリ名に空白が含まれている場合は列の選択が失敗します。

  • 以前はコマンドを連結していました&が、 は&プロセスをバックグラウンドに置くだけです。 を使用するべきでした&&が、全体として、目的を達成するのはかなり複雑になります。

答え2

私のソリューションの正しいバージョンでは、複数のコマンドを処理するために xargs が必要です。これは、次のコマンドでコマンドをラップすることで実現できます。

sh -c (or bash -c) 'Command1; Command2; .. Comandn'

したがって、正しい解決策は次のとおりです。

ls -l awk ' $8!=build_tools && $6 ~ /2013-03*/ {print $8}' | xargs -I @ sh -c 'mkdir build_tools/@; mv @ build_tools/@'

移動するファイルごとに新しいフォルダーが作成されることに注意してください。

結局のところ、他の人はより優れた専門ツールで私たちの生活を楽にしてくれていますが、古いスタイルのパイプクエリからはまだ多くのことを学べます。少なくとも私の場合はそうです :)

関連情報