Se você não citar o nome do arquivo, o shell não tem como saber que foo bar.txt
é um parâmetro e não dois ( foo
e bar.txt
). Portanto, você precisa chamar seu script assim:
./chExt.sh txt ocelot.cpp ../otherFolder/file.H cat.dog.TXT "king cobra.dat"
O próximo problema é que, quando as variáveis são expandidas, o valor resultante é dividido em espaços em branco (ou qualquer que seja o A variável $IFS
está definida como). Então, quando você escreve for i in $*
, o $*
é expandido e dividido no espaço em branco. Portanto, $i
se torna king
para uma iteração e cobra.txt
para a próxima. A maneira de contornar isso é citar a variável que você deseja expandir para que ela não seja dividida.
O que nos leva à próxima edição, que é a diferença entre $*
e $@
. Se você usar "$*"
, todos os parâmetros serão tratados como uma string longa:
$ cat foo.sh
#!/bin/sh
for i in "$*"; do
echo "$i"
done
$ foo.sh foo "bar baz"
foo bar baz
Compare o acima para:
#!/bin/sh
for i in "$@"; do
echo "$i"
done
$ foo.sh foo "bar baz"
foo
bar baz
Como você pode ver, usar "$@"
tem o efeito desejado, cada parâmetro de entrada é tratado separadamente, incluindo aquele com espaços.
Como nota final, o seu script também irá se engasgar com nomes de arquivos começando com -
e uma letra correspondente a uma opção para echo
(tente com um arquivo chamado -new
, por exemplo). Uma maneira melhor de remover a extensão é usar os recursos de manipulação de string nativos do shell. ${var%.*}
remove a string mais curta que corresponde a .
e 0 ou mais caracteres do final da variável. Em outras palavras, a extensão. Em seguida, você também precisará adicionar --
a mv
para indicar o final da opção e o início dos parâmetros, para que também possa lidar com nomes de arquivos que começam com -
(consulte a Diretriz 10 aqui .
Portanto, uma versão melhorada e funcional do seu script seria:
#!/bin/sh
newExt="$1"
shift
for fileName in "$@"
do
if test -f "$fileName";
then
# name=$(echo "$fileName" | rev | cut -f 2- -d '.' | rev)
name=${fileName%.*}
newName="$name.$newExt"
if test "$newName" != "$fileName";
then
mv -- "$fileName" "$newName"
fi
else
printf '%s: No such file\n' " $fileName"
fi
done
Leitura adicional: