
コードがJavaでEclipseプラグインであるという事実は重要ではありませんが、Eclipseプラグインプロジェクトでグローバルに名前を変更する必要がありました。
基本的に実行する手順は次のとおりです。
find . -name "*" -type f | grep -v \.git | xargs sed -i 's/com.foo/org.bar/g
- すべてのディレクトリ(除く
.git
)のsrc/com
名前を次のように変更します。src/org
- すべてのディレクトリ(除く
.git
)のsrc/org/foo
名前を次のように変更します。src/org/bar
com.foo
名前に含まれるすべてのファイルとディレクトリ名(.gitを除く)についてこのセクションをorg.bar
。
最初のステップの明示的なコマンドラインのみがあります。
他の手順を半手動で実行することもできますが、それを行う自動化された方法を見つけることが価値があると思います。ステップ2と3は同じですが、ステップ4は異なります。
私は純粋なbashコマンドラインを使ってこれをやりたいのですが、単純なbashまたはperlスクリプトを使用することもできます。
修正する:
実際、私はちょうどsrc/com
。私はまだとsrc/main/java/com
が必要ですsrc/test/java/com
。
そのために、私は次のような努力をしてきました。
find . -type d -name "com" | grep "\(/src/com\|/src/main/java/com\|/src/test/java/com\)" | xargs -n1 -i{} echo mv {} $(echo {} | sed -e 's/com/org/g')
似ていますが、最後の項目がsed
一致しないため変更されません。結果は次のとおりです。
mv ./plugins/.../src/com ./plugins/.../src/com
答え1
1
*
最初の手順では、コマンド例ではファイルをフィルタリングしないため、必要ありません。あなたがすべきことは、.git
次のようにフィルタリングすることです。
$ find . -name '.git' -prune -o -type f -print
-prune
これは完全な名前のディレクトリとその中にあるすべての内容を拒否します.git
。
grep -v ".git"
これは、sedがファイル内を編集しているため避けられないという事実を排除します。これはfindができないことです。
しかし、まだ単純化することができます(sedのポイントを引用するため)。
$ find . -name '.git' -prune -o -type f -exec sed -i 's/com\.foo/org\.bar/g' '{}' \+
これはファイル名(xargsに似ています)をsed
コマンドに蓄積します。
しかし、より良い点は次のとおりです。
$ find . -name '.git' -prune -o -type f -execdir sed -i 's/com\.foo/org\.bar/g' '{}' \+
これにより、ディレクトリごとに1つのsedインスタンスが実行されます。
2、3
ディレクトリの名前変更を実行する関数を定義しましょう。
$ renamedir (){ find "$1" -name '.git' -prune -o -type d -exec bash -c 'mv "$1" "${1//"$2"/$3}"' sh '{}' "$2" "$3" \; ; }
ステップ2:
src/com (.git を除く) のすべてのディレクトリ名を src/org に変更します。
$ renamedir 'd/src/com' 'src/com' 'src/org'
ステップ3:
src/org/foo (.git を除く) のすべてのディレクトリ名を src/org/bar に変更します。
$ renamedir 'src/org/foo' 'ogr/foo' 'org/bar'
4
ステップ4:
名前に「com.foo」を含むすべてのファイルとディレクトリ名(.gitを除く)の場合は、その部分を「org.bar」に変更します。
$ find . -name '.git' -prune -o -name "com.foo" -type f -exec bash -c 'mv "$1" "${1//"$2"/$3}"' sh '{}' "com.foo" "org.bar" \; ; }
すべて(より良い形式の)スクリプト内にあります。
#!/bin/bash
# NOTE: There are three echo to avoid execution of commands.
# If after testing, you decide that it is ok to execute commands,
# remove the echo words.
# Step 1:
### for all files (excluding .git) in . change
### file contents from com.foo to org.bar
find . -name '.git' -prune -o -type f -execdir echo sed -i 's/com\.foo/org\.bar/g' '{}' \+
renamedir (){ find "$1" -name '.git' -prune -o -type d -exec bash -c '
echo \
mv "$1" "${1//"$2"/$3}"
' sh '{}' "$2" "$3" \;
}
# Step 2:
### for all directories (excluding .git) in src/com rename to src/org
renamedir 'd/src/com' 'src/com' 'src/org'
# Step 3:
### for all directories (excluding .git) in src/org/foo rename to src/org/bar
renamedir 'src/org/foo' 'org/foo' 'org/bar'
# Step 4:
### for all file and directory names (excluding .git)
### with "com.foo" in the name, change that portion to "org.bar".
find . -name '.git' -prune -o -name "*com.foo*" -type f -exec bash -c '
echo \
mv "$1" "${1//"$2"/$3}"
' sh '{}' "com.foo" "org.bar" \; ; }
一致の他のバージョンをテストするには、次の完全なファイルツリーを作成します(後で削除するために使用しますrm -rf ./d/
)。
$ mkdir -p d/src/{{,.git}{,one},com/{{,.git}{,two},\ .git,.git/six},org/{{,.git}{,three},bar/{,.git}{,four},foo/{,.git}{,five}}}
$ touch d/src/{111,com/{222,.git/666},org/{333,bar/444,foo/555}}
$ touch d/src/{.git/{aaa,one/aaaaa},one/aaa111,com/.git{/bbb,two/bbb222},org/{.git{/ccc,three/ccc333},bar/.git{/ddd,four/ddd444},foo/.git{/eee,five/eee555}}}
元のコマンド(GNU -zオプションを使用してfind -print0と一致)は、次のものと一致します(このディレクトリで)。
$ find d/ -type f -print0 | grep -zZv \.git
find d/ -type f -print0 | grep -zZv \.git | xargs -0 printf '<%s>\n'
<d/src/org/333>
<d/src/org/foo/555>
<d/src/org/bar/444>
<d/src/com/222>
<d/src/111>
関係のないファイルは5つだけです.git
。
一般的に言うと:
.git
、およびには3つの主な一致方法がありますfind
。奇妙な点(emacs正規表現を使用)とは別に、ここでは不要な複雑な一致のみが必要です。-name
-regex
-path
-regex
Aはfind d/ -path "./.git"
正確に一致します。つまり、中間ディレクトリが1つしかありません.git
。
または(作成されたディレクトリの場合)、find . -path './d/src/.git'
次のものとのみ一致します。./d/src/.git
Aはツリーの最後のレベル(デフォルト名)でfind d/ -name ".git"
正確に一致します。.git
-name "*.git"
と両方が-path "*.git"
正確に一致します。
ランダムな文字列終わる存在する.git
。
2つのアスタリスクを追加すると、状況が複雑になり始めます。*.git*
この場合、-name
パスの最後のレベル(ファイルのデフォルト名)のみが一致しますが、2つのアスタリスクはプレフィックスのある*
名前とも一致するため(スペースに注意してください)、.git
サフィックス(多くの類似点に注意してください.gitone
):
$ find d -name '*.git*'
d/src/org/.gitthree
d/src/org/foo/.git
d/src/org/foo/.gitfive
d/src/org/bar/.gitfour
d/src/org/bar/.git
d/src/org/.git
d/src/com/.gittwo
d/src/com/.git
d/src/com/ .git
d/src/.git
d/src/.gitone
.git
ほとんどgrepと同様に、パスのすべてのレベルで一致します。 grepは複雑な正規表現を持つことができるので、grepとまったく同じではありませんが、ここで一致するのは単純な「パターン」です。d/src/com/.git/six
次の点に注意してください。
$ find d -path '*.git*'
d/src/org/.gitthree
d/src/org/foo/.git
d/src/org/foo/.gitfive
d/src/org/bar/.gitfour
d/src/org/bar/.git
d/src/org/.git
d/src/com/.gittwo
d/src/com/.git
d/src/com/.git/six
d/src/com/ .git
d/src/.git
d/src/.gitone
その後、さまざまな方法でこれらの一致を変更できます。 (not
または!
)を使用すると、次の一致が拒否されます。
いいえ(!)
find d -name '.git'
一致する場合:
d/src/org/foo/.git
d/src/org/bar/.git
d/src/org/.git
d/src/com/.git
d/src/.git
次にfind d -not -name '.git'
(またはまったく同じfind d ! -name '.git'
:)他のすべての項目と一致します。リストが非常に長いので、ここに印刷されません。
ただし、ファイルのみを選択するのは簡単です(参考ファイル666
)。
$ find d -not -name '.git' -type f
d/src/org/333
d/src/org/foo/555
d/src/org/bar/444
d/src/com/222
d/src/com/.git/666
d/src/111
in-path
はfind d -not -path '*.git*' -type f
5 つのファイルのみ一致します。
$ find d -not -path '*.git*' -type f
d/src/org/333
d/src/org/foo/555
d/src/org/bar/444
d/src/com/222
d/src/111
打つ
-prune
あるいは、すべてのディレクトリを「切り取り」または「削除」することもできます。より早い許可された一致:
$ find d \( -name '.git' -prune \) -o \( -print \)
d
d/src
d/src/org
d/src/org/three
d/src/org/333
d/src/org/.gitthree
d/src/org/foo
d/src/org/foo/five
d/src/org/foo/555
d/src/org/foo/.gitfive
d/src/org/bar
d/src/org/bar/.gitfour
d/src/org/bar/four
d/src/org/bar/444
d/src/one
d/src/com
d/src/com/.gittwo
d/src/com/222
d/src/com/two
d/src/com/ .git
d/src/111
d/src/.gitone
- 剪定後に何かがあるでしょう。通常、「-o」は-print
プルーンが一致しない項目と一致するもう1つです。ご覧のとおり、これはコマンドの5つのファイルよりも多くのファイルと一致します。 deleteのみを使用する'.git'
ように変更されました。しかし、使用するのはgrepに近いです(まだ同じではありません)。'*.git'
d/src/com/ .git
'*.git*'
$ find d \( -name '*.git*' -prune \) -o \( -print \)
d
d/src
d/src/org
d/src/org/three
d/src/org/333
d/src/org/foo
d/src/org/foo/five
d/src/org/foo/555
d/src/org/bar
d/src/org/bar/four
d/src/org/bar/444
d/src/one
d/src/com
d/src/com/222
d/src/com/two
d/src/111
これはコマンドの5つのファイル(ディレクトリではない)にのみ一致します。
$ find d \( -name '*.git*' -prune \) -o \( -type f -print \)
これは最初の5つのファイルとのみ一致します。追加すると、-type f
多くの詳細が非表示になります。
$ find d \( -name '.git' -prune \) -o \( -type f -print \)
一般的に括弧はありません(あまり明確ではありません)。
$ find d -name '.git' -prune -o -type f -print
警告:削除すると、-print
意図しない副作用が発生する可能性があります。
答え2
ファイルから置き換える
注文さまざまな理由で信頼できない:部分文字列を含むすべてのパスを除いて、.git
スペースを含むパスでは機能しないか、\'"
入力を間の文字で置き換えます。最後の問題は、ポイントの前にバックスラッシュを追加することで簡単に解決されます。ファイル名の問題は、設定で問題になることも、そうでない場合もあります。ソースツリーはかなり飼いならされる傾向があります。また、重複します(常に一致)。これはサブツリーを正しく省略する安全で簡単な代替手段です。com
foo
-name "*"
.git
find . -name .git -prune -o -type f -exec sed -i 's/com\.foo/org.bar/g' {} +
たとえば、これが発生した場合はお勧めできませんが、com.fooalso
この方法はまだ使用されます。org.baralso
これはより安全な構造です。
find . -name .git -prune -o -type f -exec sed -i -e 's/com\.foo$/org.bar/' -e 's/com\.foo\([^-_0-9A-Za-z]\)/org.bar\1/' {} +
zshを使用したファイル名の変更
ジムzmv
function autoload -U zmv
、ファイル名を変更するために使用できます。ワイルドカードパターン。私の考えでは、あなたが探しているものは実際には
zmv -w '**/com/foo' '$1/org/bar'
zmv -w '**/*com.foo' '$1/${2}org.bar'
zmv '(**/)(*)com.foo([^-_0-9A-Za-z]*)' '$1${2}org.bar$3'