%20%E3%81%A8%E6%96%87%E5%AD%97%E5%88%97%E3%82%92%E5%86%8D%E5%B8%B0%E7%9A%84%E3%81%AB%E5%90%8D%E5%89%8D%E5%A4%89%E6%9B%B4%E3%81%BE%E3%81%9F%E3%81%AF%E5%89%8A%E9%99%A4%E3%81%99%E3%82%8B%20Bash%20%E3%82%B9%E3%82%AF%E3%83%AA%E3%83%97%E3%83%88.png)
私は Bash スクリプトの使用は初めてですが、Ubuntu 16.04 のディレクトリとサブディレクトリ内のファイルのファイル名を削除または変更するために Bash スクリプトを使用するいくつかのソリューションを発見しました。たとえば、私のファイル構造は以下のようになります。つまり、 はFolderFruit,,,
メイン ディレクトリのファイル名です。SubFolderApple???.
SubFolder!!!Kiwi
とSubFolder_Food_Banana
はサブディレクトリのファイル名です。ListAppleFood
、、ListKiwiFood
はListBanana
個々のファイルのファイル名です。
>FolderFruit,,,
>> SubFolderApple??
>>> ListAppleFood.txt
>> SubFolder!!Kiwi
>>> ListKiwiFood.pdf
>> SubFolder_Food_Banana
>>> ListBanana.csv
目標は、ファイル名に含まれる句読点 (例: ? および !) と文字列「Food」を削除して、上記のファイル名を以下のように変更することです。
>FolderFruit
>> SubFolderApple
>>> ListApple.txt
>> SubFolderKiwi
>>> ListKiwi.pdf
>> SubFolderBanana
>>> ListBanana.csv
これまでのところ、以下のようにスクリプトを作成しましたが、動作しません。そのため、経験豊富な Bash または Linux ユーザーの助けをいただきたいと思います。
shopt -s globstar for f in ./**; do sed 's/\([[:punct:]]\)/\\\1/g' "$f" done
答え1
for ループを使用する代わりに、次find
のように使用できます-execdir
。
$ find -depth -mindepth 1 -type f,d -execdir \
rename 's/((Sub)?Folder|Food|List|[_,!?])//g' {} \;
コメントを詳しく説明すると、名前の変更ではファイルとディレクトリが区別されないため、(.ext を保存するのが) 非常に難しくなります。この場合、プロセスを 2 つのステップに分割し、ファイルとディレクトリを個別に処理する方がよいと思います。
$ find -mindepth 1 -depth \
\( -type f -execdir rename 's/(List|Food|[[:punct:]])(?![^.]*$)//g' {} \; \) \
-o \( -type d -execdir rename 's/((Sub)?Folder|Food|[[:punct:]])//g' {} \; \)
2 つのコマンドは基本的に同じことを行いますが、2 番目のコマンドはドットを処理できる点が異なります。