Como eu insiro um nome de arquivo ou diretório contendo espaços ou caracteres especiais no terminal?

14

Eu tenho uma coleção de arquivos e diretórios com nomes estranhos, eles contêm espaços e os caracteres especiais \ , * , ) , ( e ? . Todos eles causam problemas quando tento usá-los na linha de comando ou scripts, por exemplo:

$ cd space dir
bash: cd: space: No such file or directory

$ cat space file
cat: space: No such file or directory
cat: file: No such file or directory

$ cat (
bash: syntax error near unexpected token 'newline'

$ echo content >\
> ^C

$ ls ?
(  )  *  ?  \

Como faço para inserir nomes de arquivos ou diretórios que contenham caracteres especiais no terminal?

    
por dessert 09.12.2017 / 22:31

2 respostas

20

tl; dr : para citar um caractere especial, escape com uma barra invertida \ ou coloque-o em dobro " " ou aspas simples ' ' . Tab ↹ A conclusão cuida da cotação correta.

O que você está pedindo é chamado Citando :

  

As citações são usadas para remover o significado especial de certos caracteres ou palavras para o shell. (…) Existem três mecanismos de cotação: o caractere de escape , aspas simples e aspas duplas .    [citações tiradas de man bash ]

Citando com o caractere de escape \

  

Uma barra invertida sem aspas ( \ ) é o caractere de escape. Ele preserva o valor literal do próximo caractere que segue, com exceção de <newline> .

Para inserir um diretório ou um arquivo com um caractere especial, escape do último com \ , por exemplo:

cd space\ dir      # change into directory called “space dir”
cat space\ file    # print the content of file “space file”
echo content > \  # print “content” into file “\”
cat \(             # print the content of file “(”
ls -l \?           # list file “?”
Conclusão programável do pde% (também conhecido como Aba Conclusão) automaticamente escapa caracteres especiais com o caractere de escape bash .

Citando com aspas duplas \

  

A inclusão de caracteres entre aspas duplas preserva o valor literal de todos os caracteres entre aspas, com exceção de " " , $ , ' e, quando a expansão de histórico está ativada, \ .

Portanto, para inserir um diretório ou um arquivo com um caractere especial, escape pelo menos o último ou uma parte maior do seu nome de arquivo ou caminho com aspas duplas, por exemplo:

cd space" "dir     # change into directory called “space dir”
cd spac"e di"r     # equally
cd "space dir"     # equally
cat "space file"   # print the content of file “space file”
cat "("            # print the content of file “(”
ls -l "?"          # list file “?”

Como ! , $ e ' mantêm seu significado especial entre aspas duplas, Expansão do parâmetro , Substituição de Comando , Expansão aritmética e Expansão do histórico são executados em strings de aspas duplas.

Citando com aspas simples !

  

A inclusão de caracteres entre aspas simples preserva o valor literal de cada caractere entre aspas. Uma aspa simples pode não ocorrer entre aspas simples, mesmo quando precedidas por uma barra invertida.

Portanto, para inserir um diretório ou um arquivo com um caractere especial, escape pelo menos o último ou uma parte maior do seu nome de arquivo ou caminho com aspas duplas, por exemplo:

cd space' 'dir     # change into directory called “space dir”
cd spac'e di'r     # equal
cd 'space dir'     # equal
cat 'space file'   # print the content of file “space file”
cat '('            # print the content of file “(”
ls -l '?'          # list file “?”
echo content > '\' # print “content” into file “\”

Você pode encontrar mais informações sobre citações em ' ' / QUOTING , em wiki.bash-hackers.org e em tldp.org .

    
por dessert 09.12.2017 / 22:31
9

C-like strings e $ 'string'

Entre outras coisas, pode-se usar o tipo de cotação $'...' para usar os caracteres de barra invertida ANSI-C, como \n e \t , incluindo aqueles que você mencionou. Do manual do bash 4.3:

  

As palavras do formulário $ 'string' são tratadas especialmente. A palavra se expande   para string, com caracteres de escape de barra invertida substituídos conforme especificado   pelo padrão ANSI C.

Isto é particularmente útil em arquivos que contêm novas linhas, abas, quando você está escrevendo linhas complexas de awk, onde você precisa usar diferentes maneiras de distinguir entre aspas simples e duplas, quando os próprios nomes de arquivos contêm mix simples / duplo etc.

Por exemplo, criar e listar esses arquivos:

$ touch a$'*'b  c$'\n'd                                                     
$ ls  a$'*'b  c$'\n'd                                                       
a*b  c?d

Você pode fazer uso de valores hexadecimais de caracteres, como:

$ touch 'file(name'
$ ls file$'\x28'name
file(name

printf

Mesma ideia de antes - aproveite os caracteres de escape:

$ ls "$(printf "file\x28name")"                                             
file(name
$ echo "Hello World"  >  c$'\n'd                                            
$ cat "$(printf "c\nd")"                                                    
Hello World

Use inodes:

Cada arquivo ou diretório tem uma estrutura de dados especial associada a ele, chamada inode, que é referenciada por um número decimal específico. Assim, você pode usar isso para localizar indiretamente o arquivo com um inode específico por meio do comando find e fazer algo com ele:

$ echo "This is a test" > file$'('name1
$ ls -i
5898996 file(name1  5898997 file?name2
$ find -type f -inum "5898996" -exec cat {} \;
This is a test

Evite lidar com arquivos individuais quando você pode usar glob

Quando você não precisa lidar com arquivos individuais, apenas aproveite o * glob character no shell e cite variáveis ao passá-los para outros comandos. Faz com que lidar com nomes de arquivo difíceis seja muito mais fácil:

$ for f in ./*; do echo "$f" ; done
file    name2
file(name1

Observe o uso de ./ - uma proteção contra nomes de arquivos que podem conter - inicial neles.

    
por Sergiy Kolodyazhnyy 09.12.2017 / 22:43