From the “Terminal,” I’m wondering how can I convert all “x”s to “y”s in filenames for a specific directory on Mac OS X? Note that “x” means just anything and with “y” simply being a space.
I’d like to do this recursively, handling all sub-directories rather than only one folder at a time.
Adaptando algumas das sed
conceito de que @meatspace se refere a em seu comentário (que está localizado em esta página ) e adicionando find
na mistura eu criei este script:
find . -type d -path '*/\.*' -prune -o -not -name '.*' -type f |\
while read FULL_ITEM_PATH
do
FILE_DIRNAME=$(dirname "${FULL_ITEM_PATH}");
FILE_BASENAME=$(basename "${FULL_ITEM_PATH}");
mv "${FILE_DIRNAME}"/"${FILE_BASENAME}" "${FILE_DIRNAME}"/"$(echo $FILE_BASENAME | sed -e 's/_/ /g')";
done
Isso usará find
para localizar todos os arquivos do diretório atual em que você está - incluindo diretórios / arquivos secundários - e, em seguida, procurar sublinhados em nomes de arquivos ( _
) e alterá-los para espaços ( ) desejado. O script ignora “arquivos de ponto” / “arquivos invisíveis” como
.DS_Store
via -prune -o -not -name '.*'
e então a lógica do núcleo só age no nome real do arquivo — não no nome do diretório — separando o nome base do arquivo do nome do diretório.
Eu criei uma árvore de diretórios de teste na minha máquina Mac OS X 10.9.5 (Mavericks) com arquivos que contêm sublinhados ( _
) em seus nomes - com alguns aninhados em um diretório filho - assim:
./foo_bar
./foo_bar_two
./foo_bar_two_three
./foo_bar_two_three_bleagh.txt
./nested/foo_bar
./nested/foo_bar_two
./nested/foo_bar_two_three
./nested/foo_bar_two_three_bleagh.txt
./nested_foo/foo_bar
./nested_foo/foo_bar_two
./nested_foo/foo_bar_two_three
./nested_foo/foo_bar_two_three_bleagh.txt
Em seguida, executei esse script e eles foram alterados automaticamente para usar espaços ( ) conforme desejado:
./foo bar
./foo bar two
./foo bar two three
./foo bar two three bleagh.txt
./nested/foo bar
./nested/foo bar two
./nested/foo bar two three
./nested/foo bar two three bleagh.txt
./nested_foo/foo bar
./nested_foo/foo bar two
./nested_foo/foo bar two three
./nested_foo/foo bar two three bleagh.txt
Enquanto o script funciona, se você quiser fazer uma simples “execução a seco” para ver quais arquivos o script atuaria, substitua o comando mv
para echo
desta forma:
find . -type d -path '*/\.*' -prune -o -not -name '.*' -type f |\
while read FULL_ITEM_PATH
do
FILE_DIRNAME=$(dirname "${FULL_ITEM_PATH}");
FILE_BASENAME=$(basename "${FULL_ITEM_PATH}");
echo "${FILE_DIRNAME}"/"${FILE_BASENAME}" "${FILE_DIRNAME}"/"$(echo $FILE_BASENAME | sed -e 's/_/ /g')";
done
O bom de usar o echo
para depurar é que você também pode ver exatamente o que está acontecendo no núcleo do seu script. Assim, enquanto codifiquei esse roteiro para atender às necessidades exatas especificadas nesta pergunta, sinta-se à vontade para experimentar com ele para adaptá-lo a novas necessidades / ideias, se surgirem.