2009-10-28 18:54:06 +0000 2009-10-28 18:54:06 +0000
134
134
Advertisement

Hoe verplaats ik alle bestanden van de huidige directory naar de bovenliggende directory?

Advertisement

Hoe verplaats ik alle bestanden van de huidige directory naar de bovenste directory in linux?

Ik heb zoiets als mv *.* geprobeerd, maar dat werkt niet.

Advertisement
Advertisement

Antwoorden (11)

204
204
204
2009-10-28 19:01:58 +0000

Het commando dat u zoekt is

mv * .[^.]* ..

of (zie hieronder voor meer info):

(shopt -s dotglob; mv -- * ..)

Uitleg: het mv commando verplaatst bestanden en directories. Het laatste argument voor mv is het doel (in dit geval de map één stap “hoger” in de boom, ..). De argumenten daarvoor zijn de bronbestanden en -directories. De asterisk (*) is een wildcard die overeenkomt met alle bestanden die niet beginnen met een punt. Bestanden die beginnen met een punt (dotfiles) zijn “verborgen”. Ze worden gematched met het patroon .[^.]* (zie bewerking hieronder).

Zie de manpage waarnaar ik linkte voor meer informatie over mv.


Waarom .[^.]* in plaats van .* ?

Zoals Chris Johnsen correct opmerkt: het patroon .* komt ook overeen met . en ... Aangezien je die niet wilt (en kunt) verplaatsen, is het beter om een patroon te gebruiken dat overeenkomt met elke bestandsnaam die begint met een punt uitgezonderd die twee. Het patroon .[^.]* doet precies dat: het komt overeen met elke bestandsnaam (1) die begint met een punt (2) gevolgd door een teken dat niet een punt is (3) gevolgd door nul of meer willekeurige tekens.

Zoals Paggas wijst , zouden we ook het patroon .??* moeten toevoegen om overeen te komen met bestanden die met twee punten beginnen. Zie zijn antwoord voor een alternatieve oplossing met find .

Arjan’s antwoord noemt shopt om al die problemen met dotfiles te omzeilen. Maar dan is er nog steeds het probleem met bestanden die met een streepje beginnen. En het vereist drie commando’s. Toch vind ik het een goed idee. Ik stel voor om het als volgt te gebruiken:

(shopt -s dotglob; mv -- * ..)

Dit voert shopt uit in een subshell (dus geen tweede oproep aan shopt nodig) en gebruikt -- zodat bestanden die beginnen met een streepje niet worden geïnterpreteerd als argumenten voor mv.

45
45
45
2009-10-28 20:19:07 +0000

Kort antwoord: gebruik

find . -mindepth 1 -maxdepth 1 -exec mv -t.. -- {} +

Lang antwoord:

Het commando

mv * .* ..

zal niet werken, aangezien .* kan overeenkomen met . en ... Maar het commando

mv * .[^.]* ..

zal ook niet werken, aangezien .[^.]* niet overeenkomt met bijvoorbeeld ..filename! Wat ik in plaats daarvan doe is

mv * .[^.] .??* ..

, wat overeenkomt met alles behalve . en ... * komt overeen met alles dat niet begint met een ., .[^.] komt overeen met alle 2 karakter bestandsnamen beginnend met een punt behalve .., en .??* komt overeen met alle bestandsnamen beginnend met een punt met minstens 3 karakters.

Beter nog, je kunt

find . -mindepth 1 -maxdepth 1 -exec mv -t.. -- {} +

gebruiken, waardoor de lelijke glob hacks in mv * .[^.] .??* .. vermeden worden!

14
Advertisement
14
14
2009-10-28 20:52:27 +0000
Advertisement

Voor de volledigheid kan men de Bash-shell ook vertellen om verborgen bestanden op te nemen, door shopt te gebruiken:

shopt -s dotglob
mv -- * ..
shopt -u dotglob
8
8
8
2011-08-02 20:46:48 +0000

De mv mist de functionaliteit om verborgen bestanden te verplaatsen bij gebruik van * - dus waarom niet in plaats daarvan copy gebruiken?

cp -rf . ..

rm -rf *

Geen behoefte aan ingewikkelde oplossingen van dotglobbing en het gebruik van find commando’s.

7
Advertisement
7
7
2013-01-20 11:47:53 +0000
Advertisement
rsync -a --remove-source-files . ..

rsync is een uiterst krachtig hulpprogramma voor het kopiëren van bestanden, dat in het algemeen wordt gebruikt voor het uitvoeren van efficiënte incrementele back-ups en spiegelservers op afstand.

Met het bovenstaande commando vertellen we rsync om de inhoud van . te kopiëren naar ..

De switch -a zet recursie aan in . submappen en zet enkele andere gebruikelijke opties aan.

De switch --remove-source-files vertelt rsync om de bronbestanden te verwijderen na een succesvolle kopie, m.a.w. het laat rsync zich gedragen zoals het mv commando.

2
2
2
2011-08-12 08:12:49 +0000

Dit geminimaliseerde commando werkt op de meeste moderne shells:

\mv -- {,.{[^.],??}}* ..

Anders genoemd is een portable oplossing:

\mv -- * .[^.] .??* ..

Features:

  1. \ voorkomt dat aliassen mv ongewenst veranderen.

  2. – voorkomt dat bestandsnamen met koppeltekens (-xyz) worden geïnterpreteerd als command-line argumenten.

  3. .[^.] komt overeen met alle bestandsnamen van twee tekens die beginnen met . behalve ..

  4. .???* komt overeen met alle andere bestandsnamen van drie tekens of langer.

Naïeve implementaties:

  1. Het volgende slaat verborgen UNIX-bestandsnamen over, die beginnen met . (.bashrc).

  2. Het volgende komt overeen met … dat recursief probeert om elke directory uiteindelijk helemaal terug te verplaatsen naar / in … van de huidige werkdirectory ($PWD of pwd). Nooit gebruiken.

2
Advertisement
2
2
2009-10-28 18:59:46 +0000
Advertisement

Uiteindelijk zal het proberen met mv . mislukken omdat mv de directory waar je nu in zit niet kan unlinken. Je zou mv * .. kunnen gebruiken om de bestanden in de cwd te verplaatsen.

2
2
2
2013-10-22 22:24:11 +0000

Het is correcter om het patroon * .[!.] .??* te gebruiken dan * .[^.] .??* omdat het eerste ook werkt met oudere shells zoals ksh88:

mv -- * .[!.] .??* ..
  • -- voorkomt problemen als je een bestandsnaam hebt die begint met -
  • * komt overeen met alle bestandsnamen die niet beginnen met een .
  • er zijn geen één karakter bestandsnamen die beginnen met een . die je kunt/moet verplaatsen
  • .[!.] komt overeen met alle twee karakters bestandsnamen die niet beginnen met een .
  • er zijn geen één karakter bestandsnamen die beginnen met een .??* die je kunt/moet verplaatsen
  • . komt overeen met alle bestandsnamen van twee tekens die beginnen met een .[^.]
  • .. komt overeen met alle bestandsnamen van drie tekens (of langer) die beginnen met een .^

Met ksh88, zal het bestandsnaampatroon 0x6& in feite overeenkomen met de bestandsnamen 0x6& (die altijd bestaat) en 0x6& (die waarschijnlijk niet bestaat), met een effect tegengesteld aan wat gewenst is.

2
Advertisement
2
2
2009-10-28 19:47:28 +0000
Advertisement
mv * .??* ../.

* krijgt alle niet-stip bestanden. .??* krijgt alle . bestanden die minstens drie bytes lang zijn, wat werkt voor alle legitieme bestanden. Alles wat overblijft wil je waarschijnlijk toch rm in plaats van mv.

De ../. biedt geen directe voordelen ten opzichte van .., maar bij het doen van een move-to-directory is het een zeer goede gewoonte om aan te wennen, omdat het zal mislukken, zoals je wilt, als er iets mis is met het pad. Bijvoorbeeld, mv xyz bletch, waar je denkt dat bletch een directory is, kan je zekerder maken met mv xyz bletch/..

0
0
0
2014-05-12 23:08:11 +0000

Find en grep werken ook. Dit soort structuur kan handig zijn als je bestanden wilt selecteren op meer ingewikkelde criteria door find en grep aan te passen.

find -maxdepth 1 | egrep '^./.' # Returns all files

mv `find -maxdepth 1 | egrep '^./.'` .. # mv <all files> ..
0
0
0
2014-08-06 16:37:16 +0000

Ik denk dat de eenvoudigste oplossing voor het verplaatsen van alle bestanden naar hun bovenliggende dir. zou zijn

mv "`ls`" ../

of, Als er verborgen bestanden / mappen

gebruik:

mv "`ls -a`" ../ 2>/dev/null

Ook, stel dat je de inhoud van een map wilt verplaatsen naar een van zijn interne mappen tony(zeg)

gebruik:

mv "`ls -a`" /tony 2>/dev/null

Note:

"`ls -a`"

Om de bestanden te verplaatsen waar spaties in staan.

2>/dev/null

Is om de waarschuwing/fout te onderdrukken omdat ls -a de . en .. map ook zou afdrukken en je die niet kunt verplaatsen of kopiëren. Dus voor die mappen zal het een fout tonen (als we 2x2&/dev/null niet gebruiken) dat het ze niet kan verplaatsen en de rest zal zonder problemen verplaatst worden.

Het beste is om ls -a te vermijden als er geen verborgen bestanden zijn en gewoon ls te gebruiken.

Advertisement

Gerelateerde vragen

6
10
5
37
3
Advertisement