web-dev-qa-db-ja.com

ディレクトリではなくファイルの名前を変更する

サブディレクトリの名前を変更せずに、ディレクトリ内のすべてのファイルの名前を小文字に変更したいと思います。名前の変更機能は知っていますが、ファイルやサブディレクトリの名前を変更しますが、これは望ましくありません。手伝ってくれますか?

3
mony

すべてはPerl式で行うことができます。

通常のファイルテストである-fを使用して、(ディレクトリではなく)通常のファイルのみの名前が変更されるようにします。

これは機能します:

rename 'y/A-Z/a-z/ if -f;' ./*

./*の代わりに*を使用すると、ファイル名がダッシュ(-)で始まっていても、ファイル名がオプションとして解釈されないことが保証されます。

3
RobertL

zshの場合:

autoload zmv # best in ~/.zshrc
zmv '*(#q^/)' '${(L)f}'

ディレクトリ以外の任意のタイプのファイルの名前を変更します。または:

zmv '*(#q.)' '${(L)f}'

通常のファイルの名前を変更する場合のみ。隠しファイルも含めるには、Dglob修飾子を追加します。

例(ドライランに-nを使用):

$ ls -alQF
total 132
drwxr-xr-x   3 stephane stephane   4096 Oct 27 09:11 "."/
drwxr-xr-x 533 stephane stephane 122880 Oct 27 09:11 ".."/
drwxr-xr-x   2 stephane stephane   4096 Oct 27 09:07 "DIR"/
lrwxrwxrwx   1 stephane stephane      3 Oct 27 09:07 "DIR-LINK" -> "DIR"/
prw-r--r--   1 stephane stephane      0 Oct 27 09:07 "FIFO"|
-rw-r--r--   1 stephane stephane      0 Oct 27 09:11 ".HIDDEN FILE"
-rw-r--r--   1 stephane stephane      0 Oct 27 09:07 "HOLIDAYS IN МОСВА\nRED SQUARE.JPG"
lrwxrwxrwx   1 stephane stephane     23 Oct 27 09:08 "MY-RÉSUMÉ.PDF" -> "STÉPHANE'S RÉSUMÉ.PDF"
-rw-r--r--   1 stephane stephane      0 Oct 27 09:07 "--READ-ME--.TXT"
srwxr-xr-x   1 stephane stephane      0 Oct 27 09:09 "SOCKET"=
-rw-r--r--   1 stephane stephane      0 Oct 27 09:07 "STÉPHANE'S RÉSUMÉ.PDF"

$ zmv -n '*(#q^/)' '${(L)f}'
mv -- DIR-LINK dir-link
mv -- FIFO fifo
mv -- HOLIDAYS\ IN\ МОСВА$'\n'RED\ SQUARE.JPG holidays\ in\ мосва$'\n'red\ square.jpg
mv -- MY-RÉSUMÉ.PDF my-résumé.pdf
mv -- --READ-ME--.TXT --read-me--.txt
mv -- SOCKET socket
mv -- STÉPHANE\'S\ RÉSUMÉ.PDF stéphane\'s\ résumé.pdf

$ zmv -n '*(#q.)' '${(L)f}'
mv -- HOLIDAYS\ IN\ МОСВА$'\n'RED\ SQUARE.JPG holidays\ in\ мосва$'\n'red\ square.jpg
mv -- --READ-ME--.TXT --read-me--.txt
mv -- STÉPHANE\'S\ RÉSUMÉ.PDF stéphane\'s\ résumé.pdf

$ zmv -n '*(#qD.)' '${(L)f}'
mv -- .HIDDEN\ FILE .hidden\ file
mv -- HOLIDAYS\ IN\ МОСВА$'\n'RED\ SQUARE.JPG holidays\ in\ мосва$'\n'red\ square.jpg
mv -- --READ-ME--.TXT --read-me--.txt
mv -- STÉPHANE\'S\ RÉSUMÉ.PDF stéphane\'s\ résumé.pdf

それらのいくつかがどのようにいくつかのシンボリックリンクを壊すかを見てください。

2

あなたが試すことができます

cd directory ; rename 'y/A-Z/a-z/' $(ls -p | grep -v /$) ; cd -

ただし、findを使用することをお勧めします

cd directory ; find * -Prune -type f -exec rename 'y/A-Z/a-z/' {} + ; cd -
1
Costas

小文字への変換は、変数を小文字に植字することで実行できます。

編集:findのソリューションの場合、ソリューションをforに置き換えました。

私は最初にfindを使用して解決策を試し、-type fでのみファイルを見つけることを望んでいました。
これはうまくいくようです:
-maxdepth 1を使用したので、他のフォルダーでは何も変更しませんでした(ディレクトリ名が大文字の場合は少し難しくなります)。
これにより、

typeset -l smallfile
echo "Find solution looks OK but read more..."
find .-maxdepth 1 -type f| while read file; do
        smallfile="${file}"
        mv "${file}" "${smallfile}"
done

この構造は、スペースのあるファイル名を正しく処理できると思いました。「スペースのあるファイル」のようなファイル名でテストしました。 @Chazelasは、ファイル名がスペースで終わる( "Too bad")とソリューションが失敗することを正しくコメントしました。別のコメントは、find-コマンドを修正する方法を説明しています:find ... -print0 | while IFS= read -rd '' file(あなたのfindprint0をサポートする必要があり、ほとんどはbashzsh)。
すでにループを使用しているので、testを使用して、現在のアイテム(*で指定)が通常のファイルであることを確認することもできます。
単純なforループを使用したソリューションを見つけ、テストコードを含めてここに表示します。

#!/bin/bash
clear
rm -rf testfiles 2>/dev/null
mkdir -p testfiles/SomeDir #2>/dev/null
mkdir testfiles/"Crazy Dir" 2>/dev/null
touch testfiles/Aha testfiles/"File with Spaces" testfiles/"End with space "
ls -lQ testfiles
echo ===================
typeset -l smallfile
for file in testfiles/* # Stack's formatting thinks /* starts comment, so I close that here: */
do
   if [ -f "${file}" ]; then
        smallfile="${file}"
        # echo mv "${file}" "${smallfile}"
        mv "${file}" "${smallfile}"
   fi
done
echo ===================
ls -lQ  testfiles

現在のディレクトリについては、forループからtestdir/を削除します。

1
Walter A

このワンライナーはそれを解決します:

find path-to-search -depth -type f -exec rename 's/(.*)\/([^\/]*)/$1\/\L$2/' {} \;

チャ!

0
Stefano Martins