Transferindo arquivos com quebras de linha em nomes de arquivos no servidor Linux

3

Alguns arquivos no meu servidor foram salvos inadvertidamente com quebras de linha. Eles aparecem como file?name.txt ao examinar os arquivos no servidor. Usar scp para transferir esses arquivos para minha máquina local não funciona, pois recebo um erro "não foi possível gravar o arquivo". O erro que causou isso foi corrigido, mas não consigo acessar esses arquivos. Qual é a melhor maneira de acessar esses arquivos?

    
por user2762533 22.07.2017 / 15:36

2 respostas

3

O Newline é tão válido quanto qualquer outro caractere em um nome de arquivo no Unix. Para um shell, esse caractere tem um significado especial (ele separa comandos), portanto, precisa ser citado como qualquer outro caractere especial (como espaço, ; , | ...).

Em shells do tipo Bourne, isso pode ser feito com aspas simples ou duplas:

ls -d 'a
b'

Ou:

ls -d "a
b"

Alguns shells ( ksh93 , zsh , bash , mksh , FreeBSD sh pelo menos) também suportam:

ls -d $'a\nb'

Para scp , observe que o nome do arquivo é passado para o shell de login do usuário remoto. Quando você faz:

scp file user@host:something

ele acaba invocando o shell de login do usuário em host para interpretar o:

scp -t something

linha de comando (pelo menos com openssh). Então, se essa casca é semelhante a Bourne, tem que ser:

scp 'src/a
b' user@host:"dest/'a
b'"

Se você fizer isso:

scp 'a
b' user@host:dest/

ou

scp -r src user@host:dest/

sshd no servidor é executado:

scp -t dest/

ou

scp -r -t dest/

E os nomes dos arquivos não são passados na linha de comando do shell remoto, mas incorporados no fluxo de dados entre o cliente e o servidor scp . O que eu acho no entanto (com o openssh 7.2p2, pelo menos) é que o caractere de nova linha acaba sendo transformado em \^J (3 caracteres).

Portanto, talvez você queira usar um mecanismo diferente sobre ssh , que transfere arquivos de maneira mais confiável, como rsync ou sftp , ou tar :

tar cf - src | gzip | ssh user@host 'cd dest && gunzip | tar xpf -'

Isso também lidaria melhor com a preservação de links físicos, links de software e outros atributos de arquivo. Você também pode precisar considerar a conversão de caracteres se os nomes dos arquivos contiverem caracteres não-ASCII.

    
por 22.07.2017 / 16:17
0

Para renomear arquivos existentes que tenham novas linhas (supondo que sejam eles), com ksh93 , zsh , bash ou mksh :

for f in *$'\n'*; do mv -i -- "$f" "${f//$'\n'/}"; done

O padrão glob *$'\n'* diz para corresponder a qualquer / todos os nomes de arquivos que possuem novas linhas neles; o comando mv renomeia os arquivos removendo todas as instâncias de novas linhas deles.

    
por 22.07.2017 / 22:06