Comment entrer un fichier ou un répertoire avec des caractères spéciaux dans son nom?

44

Je veux entrer le dossier suivant dans le terminal:

Milano, Torino (Jan)-Compressed

Comment dois-je écrire la commande cdpour entrer dans ce répertoire?

Les espaces et plusieurs autres caractères spéciaux comme \, *, ), (et ?causer des problèmes lorsque je tente de les utiliser dans la ligne de commande ou des scripts, par exemple:

$ 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 ?
(  )  *  ?  \

Comment entrer des noms de fichiers ou de répertoires contenant des caractères spéciaux dans le terminal en général?

Pomario
la source
Connexes: Section 3.1.2. Citation du manuel de référence Bash .
Eliah Kagan le

Réponses:

44

Cette commande est ambiguë car les espaces sont normalement utilisés pour séparer les arguments. cd ne sait pas ce que vous voulez faire mais vous avez deux possibilités pour le résoudre:

Soit vous " masquez " les espaces (et tous les autres caractères spéciaux) afin que le terminal sache que vous entendez l'espace en tant que caractère et non en tant que séparateur:

cd Milano\,\ Torino\ \(Jan\)-Compressed

Ou vous mettez votre nom de dossier ou votre chemin entre guillemets :

cd "Milano, Torino (Jan)-Compressed"
Krystoph
la source
26

Un petit conseil: la fin de l'onglet ;-)

  1. Tapez simplement la première lettre, par exemple cd Mi(ou plusieurs lettres si nécessaire) et appuyez sur Tab. Terminal vous aidera en complétant les mots restants.

Une autre façon: glisser et déposer

  1. Si vous pouvez voir le répertoire et si vous souhaitez y accéder à l'aide d'un terminal, tapez simplement: d' cdabord, puis faites glisser le répertoire sur le terminal et appuyez sur enter.
Achu
la source
24

Écrivez-le comme:

cd 'Milano, Torino (Jan)-Compressed'

Sinon, il s'agit du Milano,nom du dossier. Cela se produit à cause des espaces dans le nom du dossier. Vous pouvez également échapper quelques caractères spéciaux:

cd Milano\,\ Torino\ \(Jan\)-Compressed/
Prateek
la source
22

tl; dr : pour citer un caractère spécial, écrivez-le avec une barre oblique inverse \ou mettez-le entre " "guillemets simples ou doubles ' '. Tab ↹L'achèvement prend soin de la citation correcte.


Ce que vous demandez s'appelle citer :

La citation est utilisée pour supprimer la signification particulière de certains caractères ou mots du shell. (…) Il existe trois mécanismes de guillemets: le caractère d'échappement , les guillemets simples et les guillemets doubles . [citations tirées de man bash]

Citer avec le personnage d'échappement \

Une barre oblique inverse ( \) est le caractère d'échappement. Il conserve la valeur littérale du caractère suivant, à l'exception de <newline>.

Donc, pour entrer dans un répertoire ou un fichier avec un caractère spécial, échappez ce dernier avec \, par exemple:

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 “?”

bashde » achèvement programmable (aka Tab ↹achèvement) échappe automatiquement des caractères spéciaux avec le caractère d'échappement \.

Citations avec guillemets " "

Caractères Enfermer guillemets préserve la valeur littérale de tous les caractères dans les citations, à l'exception de $, `, \et, lorsque l' expansion de l' histoire est activée, !.

Donc, pour entrer dans un répertoire ou un fichier avec un caractère spécial, échappez au moins ce dernier ou une partie plus importante de votre nom de fichier ou de votre chemin avec des guillemets, par exemple:

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 “?”

Comme $, `et !gardent leur signification spéciale à l' intérieur des guillemets doubles, extension des paramètres , commande Remplacement , Arithmétique et extension Histoire sont effectuées sur les chaînes entre guillemets doubles.

Citer avec des guillemets simples ' '

Le fait de placer des caractères entre guillemets simples préserve la valeur littérale de chaque caractère entre guillemets. Un seul guillemet ne peut pas apparaître entre guillemets, même s'il est précédé d'une barre oblique inverse.

Donc, pour entrer dans un répertoire ou un fichier avec un caractère spécial, échappez au moins ce dernier ou une partie plus importante de votre nom de fichier ou de votre chemin avec des guillemets, par exemple:

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 “\”

Vous pouvez en savoir plus sur man bashQuotation dans / QUOTING , sur wiki.bash-hackers.org et sur tldp.org .

dessert
la source
10

Chaînes de type C et $ 'chaîne'

Entre autres choses, on peut utiliser le $'...'type de citation pour utiliser les barres obliques inverses ANSI-C telles que \net \t, y compris celles que vous avez mentionnées. De bash 4.3 manuel:

Les mots de la forme $ 'chaîne' sont traités spécialement. Le mot se développe en chaîne, avec les caractères d'échappement avec une barre oblique inversée remplacés comme spécifié par la norme ANSI C.

Ceci est particulièrement utile pour les fichiers contenant des sauts de ligne, des tabulations, lorsque vous écrivez des lignes complexes awk dans lesquelles vous devez utiliser différentes méthodes pour distinguer les guillemets simples et doubles, lorsque les noms de fichiers contiennent eux-mêmes un méli-mélo de guillemets simple / double, etc.

Par exemple, créer et lister de tels fichiers:

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

Vous pouvez utiliser des valeurs hexadécimales de caractères, telles que:

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

printf

Même idée qu'auparavant - profitez des caractères d'échappement:

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

Utilisez des inodes:

Chaque fichier ou répertoire est associé à une structure de données spéciale appelée inode, référencée par un nombre décimal particulier. Vous pouvez donc l'utiliser pour localiser indirectement le fichier avec un inode particulier via une findcommande, et en faire quelque chose:

$ 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

Évitez de traiter des fichiers individuels lorsque vous pouvez utiliser glob

Lorsque vous n'avez pas à traiter des fichiers individuels, tirez simplement parti des *variables globales du shell et citez des variables pour les transmettre à d'autres commandes. Cela facilite beaucoup le traitement des noms de fichiers difficiles:

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

Notez l'utilisation de ./- une protection contre les noms de fichiers qui peuvent contenir une avance -.

Sergiy Kolodyazhnyy
la source
6

Pour ouvrir un dossier contenant un espace entourer de guillemets comme cd "Some Directory"ou échapper à l'espace avec une barre oblique inverse, comme: cd /home/kudic/Radna\ površina.

Corey Whitaker
la source
3
Ou échapper à l'espace avec une barre oblique inverse, comme:cd /home/kudic/Radna\ površina
Timo
Excellent point! J'ai oublié de mentionner cela. J'utilise normalement des citations par habitude, mais il est préférable d'utiliser une barre oblique inversée à long terme.
Corey Whitaker
1
Vous pouvez également utiliser des guillemets simples ( 'Radna površina') si vous ne voulez pas que les variables d’environnement ( $VARNAME) soient développées et que les commandes soient placées entre guillemets ou qu’elles $()soient exécutées (ou s’il existe des guillemets doubles dans le nom du fichier).
Eliah Kagan
3

Si ce répertoire est dans votre dossier personnel, tapez:

cd "Milano, Torino (Jan)-Compressed"

sinon donner un chemin absolu:

cd "/…/…/Milano, Torino (Jan)-Compressed"

s'il y a une double citation dans le nom du fichier, échapper à celle avec \"

Harshveer Singh
la source
Si vous commencez un chemin avec une barre oblique, il va de la racine. Vous voudrez peut-être supprimer cela.
Isaaclw
@isaaclw C'est pourquoi il l'a classé comme chemin absolu: P
1
Ah, ça fait trois points, ce qui indique un dossier "variable". J'ai supposé qu'il s'agissait de deux points, indiquant "dossier parent". Excuses.
isaaclw
3

Une autre option, mais pas la meilleure dans ce cas, consiste à utiliser des caractères génériques. Tu peux essayer:

cd *Torino*

Il est préférable d'utiliser cette méthode lorsqu'il existe un mot ou une expression distincte dans le nom d'un répertoire non partagé par d'autres. Par exemple, j'ai des points de montage / media / DataSSD et / media / DataHDD. La saisie semi-automatique ne fonctionne pas tant que je n'ai pas saisi presque la moitié du nom. Pour accéder à la partition du disque dur, je tape simplement

cd /media/*HD*

utilisateur242845
la source