Vraag FreeBSD: Directory met de naam ^ C (echt waar!) - hoe te verwijderen?


Ik heb een typfout gemaakt:

$ history
169 9:34    la /usr/local/etc/
170 9:35    sudo mkdir ^C
171 9:36    sudo mkdir /usr/local/etc/dnsmasq.d

Nu heb ik een bestand dat ^ C (ctrl + C) wordt genoemd !! Wanneer ik gebruik ls Ik zie alleen een vraagteken (waarschijnlijk vanwege de locale?)

% ls -al
total 60
drwxr-xr-x  2 root   wheel    512 Jan 21 09:35 ?        <- this one
drwxr-xr-x  5 admin  wheel    512 Jan 21 16:24 .
drwxr-xr-x  3 root   wheel    512 Jan 20 14:29 ..
-rw-r--r--  1 admin  nobody  1114 Jan 20 19:10 .cshrc
-rw-------  1 admin  wheel   6002 Jan 21 15:27 .history
-rw-r--r--  1 admin  nobody   182 Jan 20 14:29 .login
-rw-r--r--  1 admin  nobody    91 Jan 20 14:29 .login_conf
-rw-------  1 admin  nobody   301 Jan 20 14:29 .mail_aliases
-rw-r--r--  1 admin  nobody   271 Jan 20 19:04 .mailrc
-rw-r--r--  1 admin  nobody   726 Jan 20 19:05 .profile
-rw-------  1 admin  nobody   212 Jan 20 14:29 .rhosts
-rw-r--r--  1 admin  nobody   911 Jan 20 19:06 .shrc
drwx------  2 admin  nobody   512 Jan 20 15:05 .ssh
drwxr-xr-x  2 admin  wheel    512 Jan 20 19:08 bin

en

% ls -i
3611537 ?   3611534 bin

Ik wil dit bestand verwijderen. ik probeer mv en bij gebruik van tab-completion laat het zien:

% mv
^C/  bin/

Natuurlijk kan ik geen ^ C typen: - / Hoe verwijder ik dit bestand?


128
2018-01-21 15:55


oorsprong


Het is jammer dat dsw heeft POSIX niet gehaald. - Mark Plotnick
@MarkPlotnick: jammer de origineel  dsw heeft POSIX niet gehaald. - Matteo Italia
Ik denk niet dat je het ctrl + C noemde, je noemde het naar het ascii-teken dat is toegewezen aan die sneltoets, d.w.z. ETX (ascii 3) waarschijnlijk. Het lettertype van uw console heeft geen glyph voor dat teken, dus wordt een generieke vervangende glyph "?" Gebruikt. - jiggunjer
emacs -nw -f dired geeft een directory-navigator. <kbd> D </ kbd> verwijdert het bestand onder de cursor na bevestiging. - Thorbjørn Ravn Andersen
@MatteoItalia Het zijn te slechte besturingstekens in bestandsnamen en andere idioot  ideeën hebben het in POSIX gemaakt ... - pipe


antwoorden:


^V (ctrl+v) werkt als een soort escape-reeks voor de volgende toetsdruk, waarbij de bijbehorende waarde wordt ingevoegd in plaats van elke actie te ondernemen die normaal zou worden gekoppeld.

Gebruik hiervan, ^V^C (ctrl+v, ctrl+c) zou moeten werken voor het invoeren van uw moeilijke bestandsnaam in de terminal.


189
2018-01-21 16:23



Dit was waarschijnlijk de manier waarop OP in de eerste plaats hun typefout maakte. V en C staan ​​naast elkaar op het toetsenbord. - Stig Hemmer
Of ze probeerden het Windows-klembord op de bsd-terminal te gebruiken. - Joel Coel
@JoelCoel gewoonten gaan nooit dood! - Mafii
Interessant, ^V^C doet niet werk in de Zsh line-editor; de quoted-insert widget (zoek op de pagina voor ^V) voegt expliciet geen onderbrekingskarakters in. Het antwoord van Jakob (via printf) kan een meer draagbare manier zijn om een ​​controleteken te leveren in een shell-argument. - Miles
@StigHemmer: Wat ook kan gebeuren, is dat je op Ctrl-C drukt in het midden van een commando, dit vervolgens vergeet en de opdracht later kopieert en plakt. - Mehrdad


U kunt het bestand ook op inode verwijderen:

$ ls -i1
290742 foo
293246 ^C
$ find . -inum 293246 -delete

Wat je ook doet, doe het in godsnaam niet -delete voor -inum:

$ touch foo bar baz quux
$ find . -name '*u*' -delete
$ ls
bar baz foo
$ find . -delete -name 'b*'
find: `./baz': No such file or directory
find: `./bar': No such file or directory
$ ls
$ 

Gefeliciteerd, je bent gewoon weggevaagd allemaal uw bestanden. Met find, argument volgorde is belangrijk!


89
2018-01-22 03:42



Waarom niet zetten -delete voor -inum? Is dit slechts een voorzorgsmaatregel voor het geval u te vroeg op enter drukt of is de volgorde van de argumenten van invloed op de uitkomst? - detuur
@detuur: volgorde beïnvloedt resultaat. Zie bewerken. - bishop
Zet niet -delete in de opdracht, periode, totdat je de opdracht zonder hebt uitgevoerd -delete om te controleren of het vindt wat je zoekt. - Kaz
@Kaz zal niet veel helpen bij het toevoegen van -verwijderen in het midden van de opdracht - RiaD
@Kaz gebruiken -print in plaats van -delete maakt een zeer goede test. - Mark Ransom


Een andere optie is om te gebruiken rm -ri ./*; rm zal je vragen voordat je een bestand en map verwijdert, dus je hoeft alleen maar te antwoorden y naar het "slechte" bestand, en n aan alle anderen.

Eigenlijk kunt u in uw geval zelfs het aantal benodigde antwoorden verminderen door te doen rm -ri ./?, omdat je "slechte" bestand maar één teken lang is.


31
2018-01-21 20:13



select f in ?; do rm -i "$f"; break; done heeft alle voordelen van -i, zonder de pijn van het moeten beantwoorden no naar het leiden van ongewenst gedrag of per abuis het beantwoorden van ja naar een die je wilt behouden. - bishop
In het geval van OP is het een map, geen bestand. rmdir ?/ zal alle lege één-tekenige mappen verwijderen en klagen dat de andere niet-leeg zijn. - Peter Cordes
@bishop: whoa, dat wist ik niet eens select Bestond, vrij netjes! - Matteo Italia
@PeterCordes: wops, ik merkte niet dat we het hadden over mappen; ik voegde toe -r (en ./ - het is altijd gemakkelijk om te vergeten) aan mijn voorbeelden, helaas rmdir ondersteunt de -i vlag. Toch denk ik dat in dit geval de beste manier om te gaan een combinatie zou zijn van bisschop en jouw commentaar. - Matteo Italia
@MatteoItalia select bestaat alleen in sommige shells, wat waarschijnlijk de reden is waarom je het nog niet tegenkomt - scripts en oplossingen die bedoeld zijn om draagbaar te zijn, vermijden het, dus we zijn minder geneigd het te zien "in het wild". - mtraceur


Een optie is om de bestandsnaam op te zoeken met iets anders dan ls. Als je weet dat het door een woord is geproduceerd Ctrl+C, je kunt het ASCII-teken vinden dat is geproduceerd met een tabel met besturingstekens, of met een vriendelijkere interface zoals die van Python:

>>> import os
>>> os.listdir('.')
['\x03', ...]

Een andere optie zou zijn om naar een hex dump van de uitvoer van te kijken ls, met behulp van b.v. hexdump.

Dan kunt u het bestand verwijderen met (bijvoorbeeld) deze bash-opdracht:

rmdir "$(printf '\x03')"

(De dubbele aanhalingstekens zijn alleen nodig als het teken dat u probeert af te drukken zich in uw map bevindt IFS variabele, zoals \x20 of \x0A, maar het is een goede gewoonte om opdrachtsubstituties te citeren, tenzij je weet dat je wilt dat de shell veldsplitsing uitvoert, enz.)


23
2018-01-21 18:51



Ook cat -v (plus man ascii) kan helpen voor het eerste deel. - Matteo Italia
... of gebruik je os.rmdir('\x03') rechtstreeks vanuit de Python-schaal. - moooeeeep


Vaak is het in dit soort situaties gemakkelijk om een wildkaartpatroon die overeenkomt met het relevante bestand.

In uw geval zou dit eenvoudig zijn ? (aanpassing van alle bestandsnamen met precies één karakter).

Controleer gewoon of het echt overeenkomt met wat u zoekt:

ls -ld ?

En verwijder vervolgens de map:

rmdir ?

Je kunt dit ook combineren met tab voltooiing. Jij kan typen

rmdir ?

en druk op tab en b.v. in bash wordt het vervangen door

rmdir ^C/

en je kunt dan op enter drukken en het doet wat je wilt.


15
2018-01-21 21:02





U kunt Midnight Commander (mc) gebruiken om het bestand te verwijderen - selecteer gewoon met de omhoog / omlaag-knoppen en druk op F8.

Ik deed dat af en toe wanneer bestandsnamen vreemde tekens hadden vanwege codering.


11
2018-01-21 20:29



Of zo ongeveer elke andere bestandsbeheerder. - Stig Hemmer
@StigHemmer natuurlijk, sommige doen het beter dan anderen voor het weergeven van bepaalde bestandsnamen. Waarschijnlijk kan het antwoord verklaren waarom MC een optimale keuze is vergeleken met een paar andere. Ik zou het niet weten, omdat ik het nog nooit heb gebruikt. - can-ned_food


Nog een andere manier: gebruiken stat om een ​​escapetekstafbeelding van de mapnaam te krijgen:

$ stat *|grep File:
  File: ‘\003’

U kent nu een weergave van de bestandsnaam, zodat u het bestand met de naam kunt verwijderen met behulp van printf:

$ rmdir -v "$(printf '\003')"
rmdir: removing directory, ‘\003’

Of, als u bash gebruikt, kunt u vermijden printf:

$ rmdir -v $'\003'
rmdir: removing directory, ‘\003’

7
2018-01-22 10:25



BTW als de shell bash is, $'\x03' is eenvoudiger dan het aanroepen van printf. Hetzelfde voor FreeBSD sh dat uitgebreid wordt via de POSIX-shell met enkele smakelijke functies. - Netch
@Neem een ​​goed punt over bash's $'...', maar ik vermijd in het algemeen een nutteloze conversie van octaal naar hexadecimaal. Bijv. wat als het bestand werd genoemd '\111' (in stat output)? Zou je het nog steeds verwijderen met $'\x49'? Gebruik beter dezelfde volgorde als stat gaf je: in het geval van het OP, rmdir $'\003'. - Ruslan


Een oplossing die voor mij heeft gewerkt is:

rm ./[Tab][Tab][Tab]...

om door de beschikbare bestanden te bladeren totdat ik degene vind die ik wil verwijderen.

Maar je moet wel de noodzakelijke instellingen in je shell om dat te laten werken.


6
2018-01-22 08:31



^ C is echt vroeg in het tabblad, dus een +1 voor jou. - joshudson