親フォルダの後に特定のファイルの名前を変更し、中央フォルダに移動する必要がある問題があります。これを行う方法はありますか? Synology NASで実行したいです。
Root
|-Subf1
| |-File.txt
| |-File.doc
| |-Subf1subf1
| | |-File.xml
| | |-File.xls
| |-Subf1subf2
| | |-File.pptx
| | |-File.docx
|
|-Subf2
| |-File.txt
| |-File.doc
| |-Subf2subf1
| | |-File.xml
| | |-File.xls
結果は次のとおりです。
Root
|-Subf1
| |-Subf1.txt
| |-Subf1.doc
| |-Subf1.xml
| |-Subf1.xls
| |-Subf1.pptx
| |-Subf1.docx
|
|-Subf2
| |-Subf2.txt
| |-Subf2.doc
| |-Subf2.xml
| |-Subf2.xls
拡張子がすべて異なるため、ファイルの上書きに問題はありません。
答え1
#! /bin/bash
shopt -s globstar #enabled for '**' to match all files &directories recursively
#shopt -s dotglob #uncomment to enable to match on hidden files/directories too
cd /path/to/directory/Root
for pathname in ./**/*; do
[[ -f "$pathname" ]] && echo mv -v -- "$pathname" "${pathname%%/*}/${pathname%%/*}.${pathname##*.}";
done
##then remove remained empty directories
for pathname in ./**/*; do
[[ -d "$pathname" && -z "$(ls -A -- "$pathname")" ]] && rm -r -- "$pathname";
done
[[ -f "$pathname" ]]
ファイル$pathname
であることを確認してくださいf
${pathname%%/*}
:使用シェルパラメータ拡張、パラメータから最長のサフィックスを削除しますpathname
。最初のスラッシュ文字の前の内容をすべて切り取ります/
。${pathname##*.}"
:同じですが、引数から最長の接頭辞を削除し、pathname
最後のドット文字まですべてを切り捨てます.
。[[ -d "$pathname" ]]
ディレクトリ$pathname
であることを確認してください。d
... && -z "$(ls -A -- "$pathname")"
次に、デフォルト名が次のようになっていることを確認します。pathname
これはディレクトリです。空ですか?。
echo
結果が満足であれば削除してください。
答え2
POSIX的に:
cd Root &&
LC_ALL=C find . \
-name '.?*' -prune -o \
-path './*/*/*' \
-prune \
-name '*.*' \
-type f \
-exec sh -c '
ret=0
for file do
ext=${file##*.}
sub=${file%/*/*}
subname=${sub##*/}
echo mv -i "$file" "$sub/$subname.$ext" || ret=$?
done
exit "$ret"' {} +
echo
(満足すれば削除)
その後、次のコマンドを使用して空のディレクトリを削除できます。
find . -depth -type d -exec rmdir {} + 2> /dev/null
またはfind
非標準-empty
の合計をサポートする場合-delete
:
find . -type d -empty -delete
(-delete
ヒント-depth
)。