2009-08-24 6 views
1

可能性の重複:私のような(私はfind bla -name "*.so"から入手)のファイルで点灯している
makefile: how to add a prefix to the basename?はbash:ファイルだけのリストのベース名を変更する方法

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

と私は彼らにsuコマンドの名前を変更したいですそれがなるとCH:

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

...すなわちベース名

にbashでそれを行う方法上の任意のアイデアを接頭辞 'LIB' を追加しますか?線に沿って

+0

でそれらの内部ディレクトリとファイルが重複した...他の質問は、どのように同じことを達成するのではなく、直接bashスクリプトで – dm76

答えて

5

何か:

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 

はそれを行う必要があります。ファイル内のファイル名のリストを読み込むコードを、スクリプト内にそのまま記述するのではなく、追加することもできます。

+0

おかげで求めているのに対し、この作りでどのようにこれを求めていません(私が推測する)Aaronは引用符を付け加えることが良い点だ。 – unwind

+0

もちろん、私はdirnameについて忘れてしまったので、簡単にパスを分割する方法を見ることができませんでした...ありがとう! mv $ a $ dn/lib $ fnそうでなければ、bashはdnとfnをバックコマンドの代わりに '$()'を使うシェルコマンド – dm76

+0

+1と考えるでしょう。 –

1

mmvをお試しください:

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

mmv "*" "lib#1"でも動作しますが、それはあまり安全です)。

mmvがインストールされていない場合は、取得してください。

+0

mmvは強力なサウンドです!情報のおかげで – dm76

0

ベース名とdirnameがあなたの友人:)です

あなたは(私はbashの構文を言い訳 - それは少し錆びです)このような何かをしたい:パンチを打た

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

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

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

ループ処理は不要です。findは既にファイルをリストする再帰的な作業を行っています。このコードは "mv"コマンドを1つずつ作成して実行します。 "mv"コマンドを実行せずに見るには、単にシェル部分 "| bash"へのパイプを取り除くだけです。

findのprintfコマンドは、かなりスケーラブルになる多くの変数を理解しています。私は、ここでしか2を使用するために必要な:

  • %時間:ディレクトリ
  • %のF:ファイル名

それをテストする方法:これは(まだ何も最初に実行しません

ラン、画面上の印刷行のみ):

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

スクリプトが実行するすべてのコマンドを表示します。結果に満足すれば、lessの代わりにbashにパイプして実行してください。

find . -name "*.so" -printf "mv '%h/%f' '%h/lib%f'\n" | bash 
+0

findコマンドに適切な 'mindepth'と' maxdepth'を追加し、[shudder]にスペースがある場合にはファイルとディレクトリ名を引用符で保護したいかもしれません。 'find。 -mindepth 2 -maxdepth 2 -name "* .so" -printf "mv"%h /%f "'%h/lib%f' \ n" | sh' –

+0

私は引用符で同意し、私は結果として自分のコードを更新しました。 –

+0

このソリューションには多くの結果に問題がありますか?例えば。最大のコマンドの長さなどを打つ? –

0

私は$のNFM(あなたが本当に必要とするよりも、多分それ以上)に基づいて、偶発的な騒乱

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 
2

Aもう少し堅牢かつ一般的な解決策は

だろう防ぐために、mvコマンドをコメントアウトしました注
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 <を読ん
  • -print0 + IFS = + -d $「/ 0」をあなたも名前を変更することができるように、
  • ソート-Rzが最初に深いパスの名前を変更し
  • ファイル名に改行することができます一度
関連する問題