ファイルとディレクトリのすべてのスペースを再帰的に置き換える次のスクリプトがあります。
################### SETUP VARIABLES #######################
number=0 # Number of renamed.
number_not=0 # Number of not renamed.
IFS=$'\n'
array=( `find ./ -type d` ) # Find catalogs recursively.
######################## GO ###############################
# Reverse cycle.
for (( i = ${#array[@]}; i; )); do
# Go in to catalog.
pushd "${array[--i]}" >/dev/null 2>&1
# Search of all files in the current directory.
for name in *
do
# Check for spaces in names of files and directories.
echo "$name" | grep -q " "
if [ $? -eq 0 ]
then
# Replacing spaces with underscores.
newname=`echo $name | sed -e "s/ /_/g"`
if [ -e $newname ]
then
let "number_not +=1"
echo " Not renaming: $name"
else
# Plus one to number.
let "number += 1"
# Message about rename.
echo "$number Renaming: $name"
# Rename.
mv "$name" "$newname"
fi
fi
done
# Go back.
popd >/dev/null 2>&1
done
echo -en "\n All operations is complited."
if [ "$number_not" -ne "0" ]
then echo -en "\n $number_not not renamed."
fi
if [ "$number" -eq "0" ]
then echo -en "\n Nothing been renamed.\n"
elif [ "$number" -eq "1" ]
then echo -en "\n $number renamed.\n"
else echo -en "\n Renamed files and catalogs: $number\n"
fi
exit 0
配列をディレクトリで埋める方法で動作します。
array=( `find ./ -type d` ) # Find catalogs recursively.
このスクリプトを特定のディレクトリで強制的に動作させるにはどうすればよいですか?
array=( `find /my/start/directory/ -type d` ) # Find catalogs recursively.
私はそれが正しいことを再確認し、誤ってサーバー上のすべてのファイル名を変更したくないので、(単に実行するのではなく)ここに尋ねます!
ベストアンサー1
mv
コマンドをコメントアウトして実行し、提案された変更でスクリプトをテストできます。スクリプトであまりにも多くのことが行われているので、すぐに大丈夫だとは言えませんが、array
現在のスクリプトが有効な場合は混乱する可能性があります(明らかに改行文字を含むディレクトリ名がない、配列がめちゃくちゃになった、または名前が開始されません)。ダッシュを使用mv
し、echo
いくつかの場所では)大丈夫だろうと思います。
ディレクトリやその他のファイルのファイル名のスペースをアンダースコアに繰り返し変更します。
topdir=.
find "$topdir" -depth -name "* *" -exec bash -c '
for pathname do
# $pathname will have at least one space in it
newname=${pathname##*/} # get basename
newname=${newname// /_} # replace spaces with underscores
printf "Would move %s to %s\n" "$pathname" "${pathname%/*}/$newname"
# mv "$pathname" "${pathname%/*}/$newname"
done' bash {} +
$topdir
名前の内または下に少なくとも1つのスペースを含むすべての項目を見つけます。これらのパス名を収集してインラインbash
スクリプトに提供します。このスクリプトは、各パス名のファイル名部分を抽出し、スペースを下線で置き換えます。実際の作業は安全上の理由からmv
注釈付けされています。
-depth
まだアクセスしていないディレクトリの名前を変更したくないため、このオプションが必要です。これにより、find
ディレクトリ階層の深さ優先探索が実行されます。
使用されるパラメータの置換:
${variable##*/}
:値の最後のスラッシュの前のすべての項目を削除しますvariable
。とほぼ同じです$( basename "$variable" )
。${variable%/*}
:最後のスラッシュの後のすべてのエントリを削除します。とほぼ同じです$( dirname "$variable" )
。${variable//pattern/replacement}
:pattern
一致する値のすべてを置き換えます(これは拡張です)。replacement
variable
bash
新しいファイル名がすでに存在するかどうかを確認しません。これは内部スクリプトで簡単に実行できますbash
。
if [ -e "${pathname%/*}/$newname" ]; then
printf "Will not rename %s, new name exists\n" "$pathname" >&2
else
printf "Would move %s to %s\n" "$pathname" "${pathname%/*}/$newname"
# mv "$pathname" "${pathname%/*}/$newname"
fi
テスト:
$ tree
.
|-- a directory
| `-- yet another file
|-- script.sh
|-- some file
`-- some other file
1 directory, 4 files
$ sh script.sh
Would move ./some file to ./some_file
Would move ./some other file to ./some_other_file
Would move ./a directory/yet another file to ./a directory/yet_another_file
Would move ./a directory to ./a_directory
関連: