A saída que recebo através de “echo” funciona como um comando quando colado no terminal, mas não no script

3

Estou tentando alterar os arquivos gerados por um aplicativo que, infelizmente, geralmente contêm espaços. Eu consegui obter "eco" para me dar saída que funciona se copiar colado no terminal, mas quando eu tento fazer o comando, ele não funciona. Eu olhei para this answer, que me ajudou antes, mas mesmo a sintaxe" $ {x} "não parece funcionar neste caso.

#!/bin/sh
cd ~/Data
IFS=$'\n';for i in $(ls); do
    echo "$i";
    filename="$i"
    date=$(date -n +%Y-%m-%d)
    new_filename="$date$filename"
    echo mv \'"${filename}"\' \'"${new_filename}"\'
    mv \'"${filename}"\' \'"${new_filename}"\'
done;
    
por Var87 28.01.2015 / 15:16

3 respostas

5

O principal problema é que você faz um loop pela saída do comando ls . Use glob * em vez disso:

#!/bin/sh
cd ~/Data
for i in *; do
    echo "$i"
    filename="$i"
    date=$(date -n +%Y-%m-%d)
    new_filename="${date}${filename}"
    echo mv "${filename}" "${new_filename}"
    mv -- "${filename}" "${new_filename}"
done

Além disso, adicionei -- a mv para tratar corretamente os arquivos cujos nomes começam com - . E btw meu comando date não tem -n opção, mas deixo como você pode ter versão diferente.

    
por 28.01.2015 / 15:24
1

O outro problema que você teve foi que você também tinha cotações extras na linha mv. Quando você está usando o echo para imprimir um comando que será copiado para um shell, você precisa citar tudo duas vezes, uma para esse shell e uma para o segundo. seu echo mv funcionou bem, desde que o nome do arquivo não comece com um traço ou contenha uma aspa simples. O mv só precisava ser citado uma vez.

Aqui está como eu iria reescrever o seu trecho.

#!/bin/bash
cd ~/Data
date="$(date -n +%Y-%m-%d)"

for filename in *; do
    echo "${filename}"
    new_filename="$date$filename"
    filename_e="$(echo "$filename"|sed -e 's!\('\''\)!\!')"
    new_filename_e="$(echo "$new_filename"|sed -e 's!\('\''\)!\!')"
    echo mv -- \'"${filename_e}"\' \'"${new_filename_e}"\'
    mv -- "${filename}" "${new_filename}"
done;

Esta versão irá renomear corretamente qualquer arquivo com qualquer caractere no nome. a única limitação é que o comando echoed pode produzir comandos que não funcionam em arquivos que possuem uma nova linha no nome.

    
por 28.01.2015 / 22:05
-1

Você só precisa tratar o nome do arquivo adicionando um caractere de escape \ antes do espaço.

filename=$(echo $i|sed 's/ /\ /g')
mv $filename $new_filename
    
por 28.01.2015 / 15:31