Você pode usar o comando basename
aqui:
touch "$folder/$(basename "$filePng" .png).txt"
Observe o $folder/
adicional. Isso é necessário porque o comando basename remove o caminho de.
Eu tenho esse script
#!/bin/bash
folder='/home/data/mnist/training'
for filePng in $folder/*
do
touch $filePng.txt
done
Funciona, só que, para um arquivo chamado 001.png
, ele cria 001.png.txt
em vez de 001.txt
.
Como posso modificar isso?
Você pode usar o comando basename
aqui:
touch "$folder/$(basename "$filePng" .png).txt"
Observe o $folder/
adicional. Isso é necessário porque o comando basename remove o caminho de.
Você pode remover a extensão existente usando os recursos de expansão do shell
${parameter%pattern}
O 'padrão' é comparado com o final do 'parâmetro'. O resultado é o valor expandido de 'parâmetro' com o correspondência mais curta excluída.
Portanto, no seu caso, substitua $filePng.txt
por "${filePng%.png}.txt"
Com a variação do que o steeldriver já mencionou - expansão de parâmetros - podemos usar a substituição de strings para fazer o trabalho. Além disso, você deve citar variáveis. Abaixo está o seu script editado.
#!/bin/bash
folder='/home/data/mnist/training'
for filePng in "$folder"/*
do
touch "${filePng/.png/.txt}"
done
Se você tiver muito de arquivos para criá-lo, valeria a pena “tocar” mais de um arquivo por vez, para que você não precise forçar um novo processo para cada um dos arquivos. eles (o que leva algum tempo se for realizado milhares de vezes).
xargs
Esta opção fornecerá vários caminhos para o comando touch
de uma vez, geralmente alguns milhares ou qualquer que seja o sistema que possa caber em uma única linha de comando.
find "$folder" -mindepth 1 -maxdepth 1 -name '*.png' -print0 |
sed -ze 's/\.png$/.txt/' |
xargs -r0 -- touch --
Esta opção não executa touch
, mas usa recursos de shell Bash / Bourne / POSIX, que não requerem sub-processos.
for f in "$folder"/*.png; do
: >> "${f%.png}.txt"
done
Se você tiver certeza de que não tem arquivos com .png
em algum lugar no meio do nome, poderá usar apenas uma matriz com a expansão de parâmetros:
pngs=( /path/to/pngs/*.png )
touch "${pngs[@]/.png/.txt}"
Isso armazena todos os caminhos para os arquivos que terminam em .png
em uma matriz e, em seguida, usa a expansão de parâmetro para criar a lista de .txt
arquivos, substituindo .png
por .txt
em cada um.
Tenha em mente que isso será interrompido se você tiver tantos arquivos que nem todos podem ser passados como argumentos para a mesma invocação de touch
.