web-dev-qa-db-ja.com

同じディレクトリ名を持つサブディレクトリから相対的な上位/親ディレクトリにファイルを移動する方法は?

だから、私はこのようなディレクトリ構造を持っています:

parent/
├── sub1
│   └── source
│       └── file1
│       └── file2
├── sub2
│   └── sub2.1
│       └── source
│           └── something1
│           └── something2
└── sub3
    └── sub3.1
        └── sub3.1.1
            └── source
                └── other.Zip

すべてのファイル(異なるファイル名)をsourceという名前のすべてのディレクトリの相対的な上位/親ディレクトリに移動したい。したがって、結果は次のようになります。

parent/
├── sub1
│   ├── file1
│   ├── file2
│   └── source
├── sub2
│   └── sub2.1
│       ├── something1
│       ├── something2
│       └── source
└── sub3
    └── sub3.1
        └── sub3.1.1
            ├── other.Zip
            └── source

これを達成する簡単な方法(one liner)はありますか、おそらくfindコマンドを使用しますか?できれば、私にとって理解するには複雑すぎないものをお勧めします。 :D私はLinuxが初めてです。

編集:ソリューションからbashスクリプトを作成します(そのため、簡単に使用できます)。例:./movefiles.sh myfolderそれで、できれば、ソリューションは、umm変数、特に.(隠しディレクトリの場合)、#@などのシンボルを持つ変数に簡単に対応できます。

5
Lukman Hakim

findソリューションが必要な場合は、これを使用できます。

find parent -name "source" -type d -exec bash -c 'cd "$1"; mv * ..' bash {} \;

説明:

  • find parent -name "source" -type d-sourceparentという名前のディレクトリごとに...
  • -exec bash -c '...' bash {} \;-$0としてbashとして$1としてディレクトリパスを使用してBashを呼び出します
  • cd "$1"; mv * ..-ディレクトリにcd;すべてのコンテンツを1レベル上に移動します。
    • 代替:mv "$1"/* "$1/.."

これは、多かれ少なかれ デザートの答え に基づいています。

隠しファイルを含める

find parent -name "source" -type d -exec bash -c 'shopt -s dotglob; cd "$1"; mv * ..' bash {} \;
  • shopt -s dotglob-グロブに隠しファイルを含める
4
wjandrea

サプライズがあるかもしれないこうした種類のタスクの場合、最良の方法の1つは "script-a-script"です。タスクを実行するために、通常非常に反復的なスクリプトを出力するコマンドを実行します。それが正しいことに満足したら、それをshにパイプして実行します。これは複雑な問題をはるかに単純な編集問題に変え、それは非常に一般的な手法であり、この厄介ないくつかのファイルの二階上の問題だけでなく、あらゆる種類の問題に適用できます。これには、エキゾチックなシェル構造を使用しないという利点があり、すべてのシェルで機能します(純粋なPosix shbashcshなど)。実行される前にすべての基本的なコマンドが表示されるため、これは"look-before-you-leap"の良い例です。

まず、変更するすべてのディレクトリを見つけます。

$ find . -type d -name source

これは与える

./sub3/sub3.1/sub3.1.1/source
./sub2/sub2.1/source
./sub1/source

次に、コンテンツを1つのディレクトリに移動するディレクトリごとに、実行するコマンドを考えます。

$ mv $dir/* $dir/..

awk(またはsedなど)を使用してコマンドを記述します。したがって、ディレクトリのリストをawkにパイプします。

$ find . -type d -name source \
  | awk '{printf("mv %s/* %s/..\n", $0, $0);}'
mv ./sub3/sub3.1/sub3.1.1/source/* ./sub3/sub3.1/sub3.1.1/source/..
mv ./sub2/sub2.1/source/* ./sub2/sub2.1/source/..
mv ./sub1/source/* ./sub1/source/..

コマンドが正しいことがわかるまで、必要な回数だけ慎重に編集します。

次に、それらすべてをshにパイプして実際に実行します。

$ find . -type d -name source \
  | awk '{printf("mv %s/* %s/..\n", $0, $0);}' \
  | sh

最終出力が何をしているのかを言って、最初のエラーで終了することがよくあるので、sh -e -xを使用します。

$ find . -type d -name source  \
  | awk '{printf("mv %s/* %s/..\n", $0, $0);}' \
  | sh -e -x

この編集でawkに自信がない場合は、sedまたは純粋なfindでそれを行うことができます

find . -type d -name source | sed 's|\(.*\)|mv \1/* \1/..|'  # sed
find . -type d -name source -exec echo 'mv {}/* {}/..' ';'   # find/echo
2
jonathanjo

以下のコードを使用して、必要なものを取得できます。

dir=$(find . -name 'source' | sed s:source::)
for path in $dir; do
    mv "$path"source/* "$path"
done

findコマンドは、親からソースディレクトリへのディレクトリパスを返します。このfind . -name 'source' '。'は親ディレクトリを表し、「ソース」は検索するサブディレクトリを表します。

sedコマンドは、sourceコマンドの結果からfindを削除します。

そして、残りは単なる反復(for)と移動コマンド(mv)です。

2
Sathish Kanna

ネストされたfindコマンドは1行でジョブを実行しますが、これは少し風変わりに見えるかもしれません。 ;-)

具体的には:

find . -name source -type d -exec sh -c 'find "$0" -type f -execdir mv "{""}"  .. \;' {} \;

説明:

  • find . -name source -type dは、現在の(.)ディレクトリーでsourceという名前のすべてのディレクトリーを検出します。

  • -exec sh -c '...' {} \;は、見つかったすべてのディレクトリに対してコマンド'...'shを実行し、ディレクトリ名を{}にプラグインし、さらに、実行されたshの変数$0{}の内容で定義します(shマンページのオプション-cを参照)

  • sh -cへの引数、'find "$0" -type f ... 'は、ディレクトリ$0内のすべてのファイルを検索します

  • 最後に、... -execdir mv "{""}" ..は、見つかったファイル{}(ここでは、上流の"{""}"による置換を防ぐために-execとして非表示)を(ディレクトリローカル-したがって-execdir)親ディレクトリ..に移動します

実行例:

marcus@gargabuntu:~/temp$ tree
.
├── sub1
│   └── source
│       ├── file1
│       └── file2
├── sub2
│   └── sub2.1
│       └── source
│           ├── something1
│           └── something2
└── sub3
    └── sub3.1
        └── sub3.1.1
            └── source
                └── other.Zip

9 directories, 5 files
marcus@gargabuntu:~/temp$ find . -name source -type d -exec sh -c 'find "$0" -type f -execdir mv "{""}"  .. \;' {} \;
marcus@gargabuntu:~/temp$ tree
.
├── sub1
│   ├── file1
│   ├── file2
│   └── source
├── sub2
│   └── sub2.1
│       ├── something1
│       ├── something2
│       └── source
└── sub3
    └── sub3.1
        └── sub3.1.1
            ├── other.Zip
            └── source

9 directories, 5 files
1
marcus

シンプルなもの

dir='source'
for i in `find . -name  "*" | grep $dir/*| grep -v "$dir$"`; do
mv "$i" "${i%$dir/*}"
done

テスト

$ cd Desktop/test/
/Desktop/test$ tree
.
├── sub1
│   └── source
│       ├── file1
│       └── file2
├── sub2
│   └── sub2.1
│       └── source
│           ├── something1
│           └── something2
└── sub3
    └── sub3.1
        └── sub3.1.1
            └── source
                └── other.Zip

9 directories, 5 files
/Desktop/test$ dir='source'
/Desktop/test$ for i in `find . -name  "*" | grep $dir/*| grep -v "$dir$"`; do
>    mv "$i" "${i%$dir/*}"
> done
/Desktop/test$ tree
.
├── sub1
│   ├── file1
│   ├── file2
│   └── source
├── sub2
│   └── sub2.1
│       ├── something1
│       ├── something2
│       └── source
└── sub3
    └── sub3.1
        └── sub3.1.1
            ├── other.Zip
            └── source

9 directories, 5 files
/Desktop/test$ 
0
Vijay