2

重複の可能性:
makefile: ベース名に接頭辞を追加するには?

次のような一連のファイル(から取得find bla -name "*.so")があります。

/bla/a1.so /bla/a2.so /bla/blo/a3.so /bla/blo/a4.so /bla/blo/bli/a5.so

次のように名前を変更したいと思います。

/bla/liba1.so /bla/liba2.so /bla/blo/liba3.so /bla/blo/liba4.so /bla/blo/bli/liba5.so

... つまり、接頭辞「lib」をベース名に追加します

bashでそれを行う方法について何か考えはありますか?

4

6 に答える 6

7

次のようなもの:

for a in /bla/a1.so /bla/a2.so /bla/blo/a4.so
do
  dn=$(dirname $a)
  fn=$(basename $a)
  mv "$a" "${dn}/lib${fn}"
done

するべきです。もちろん、スクリプトでファイル名を逐語的にリストするのではなく、ファイルからファイル名のリストを読み取るコードを追加することもできます。

于 2009-08-24T12:37:40.347 に答える
6
find . -name "*.so" -printf "mv '%h/%f' '%h/lib%f'\n" | bash

このコードは、現在のディレクトリとサブディレクトリ内のファイルの名前を変更して、.so ファイル名の前に「lib」を追加します。

findファイルを一覧表示するための再帰的な作業が既に行われているため、ループは必要ありません。このコードは、「mv」コマンドを 1 つずつ作成して実行します。「mv」コマンドを実行せずに表示するには、シェル部分「| bash」へのパイプを削除するだけです。

findの printf コマンドは、かなりスケーラブルな多くの変数を理解します。ここでは 2 つだけ使用する必要がありました。

  • %h: ディレクトリ
  • %f: ファイル名

それをテストする方法:

最初にこれを実行します (まだ何も実行しません。画面に行を出力するだけです):

find . -name "*.so" -printf "mv '%h/%f' '%h/lib%f'\n" | less -S

これにより、スクリプトが実行するすべてのコマンドが表示されます。満足のいく結果が得られた場合は、 のbash代わりに にパイプして後で実行するだけですless

find . -name "*.so" -printf "mv '%h/%f' '%h/lib%f'\n" | bash
于 2009-08-24T12:43:12.203 に答える
2

whileマルチライナー

$ nfmに基づくもう少し堅牢で一般化されたソリューション(おそらく実際に必要なものよりも多い)は

while IFS= read -r -u3 -d $'\0' FILE; do
    DIR=`dirname $FILE`;
    FILENAME=`basename $FILE`;
    mv $FILE ${DIR}/lib${FILENAME};
done 3< <(find bla -name *.so -print0 | sort -rz)

これは非常に堅牢です。

  • 読み取り-u3および3<はstdinに干渉しません
  • -print0 + IFS = + -d $'/ 0'は、ファイル名の改行を許可します
  • sort -rzは、最初に深いパスの名前を変更するため、ディレクトリとその中のファイルの名前を一度に変更することもできます。

find -execdir+rename

PATHの煩わしさがなければ、これは完璧です。Linuxで複数のファイルを検索して名前を変更するを参照してください。

于 2012-06-20T08:14:45.690 に答える
1

試してくださいmmv

cd /bla/
mmv "*.so" "lib#1.so"

mmv "*" "lib#1"これも機能しますが、安全性は低くなります)。

インストールしていない場合はmmv、入手してください。

于 2009-08-24T12:38:55.027 に答える
0

basename と dirname はあなたの友達です:)

あなたはこのようなものが欲しいです(私のbash構文を許してください-それは少し錆びています):

for FILE in `find bla -name *.so` do
    DIR=`dirname $FILE`;
    FILENAME=`basename $FILE`;
    mv $FILE ${DIR}/lib${FILENAME};
done

殴られた!

于 2009-08-24T12:40:06.150 に答える
0

偶発的な混乱を防ぐために mv コマンドをコメントアウトしたことに注意してください

for f in *
do
    dir=`dirname "$f"`
    fname=`basename "$f"`
    new="$dir/lib$fname"
    echo "new name is $new"
    # only uncomment this if you know what you are doing
    # mv "$f" "$new" 
done
于 2009-08-24T12:45:04.950 に答える