GNU/Linux >> Znalost Linux >  >> Linux

Proč nefunguje find -exec mv {} ./target/ +?

Narazil jsem na stejný problém na Mac OSX pomocí ZSH shell:v tomto případě neexistuje -t možnost pro mv , takže jsem musel najít jiné řešení. Následující příkaz však uspěl:

find .* * -maxdepth 0 -not -path '.git' -not -path '.backup' -exec mv '{}' .backup \;

Tajemství bylo citovat rovnátka . Není nutné, aby složené závorky byly na konci exec příkaz.

Testoval jsem pod Ubuntu 14.04 (pomocí BASH a ZSH shelly), funguje to stejně.

Při použití + znaménko, skutečně se zdá, že musí být na konci exec příkaz.


Manuálová stránka (nebo online GNU manuál) do značné míry vše vysvětluje.

najít -exec příkaz {} \;

Pro každý výsledek command {} je proveden. Všechny výskyty {} jsou nahrazeny názvem souboru. ; má předponu lomítko, aby jej shell nemohl interpretovat.

najít příkaz -exec {} +

Každý výsledek je připojen k command a následně proveden. Vezmeme-li v úvahu omezení délky příkazu, domnívám se, že tento příkaz lze provést vícekrát, přičemž mě podporuje manuálová stránka:

celkový počet vyvolání příkazu bude mnohem menší než počet odpovídajících souborů.

Všimněte si tohoto citátu z manuálové stránky:

Příkazový řádek je vytvořen v podstatě stejným způsobem, jakým xargs vytváří své příkazové řádky

Proto nejsou povoleny žádné znaky mezi {} a + kromě mezer. + způsobí, že find zjistí, že argumenty by měly být připojeny k příkazu stejně jako xargs .

Řešení

Naštěstí GNU implementace mv může přijmout cílový adresář jako argument buď s -t nebo delší parametr --target . Jeho použití bude:

mv -t target file1 file2 ...

Vaše find příkaz se změní na:

find . -type f -iname '*.cpp' -exec mv -t ./test/ {} \+

Z manuálové stránky:

-exec příkaz;

Vykonat příkaz; true, pokud je vrácen stav 0. Všechny následující argumenty k nalezení jsou považovány za argumenty příkazu až do argumentu sestávajícího z `;' se narazí. Řetězec `{}' je nahrazen aktuálním názvem souboru, který se zpracovává všude, kde se vyskytuje v argumentech příkazu, nejen v argumentech, kde je sám, jako v některých verzích find. Obě tyto konstrukce může být nutné escapovat (s '\') nebo citovat, aby byly chráněny před expanzí pomocí shellu. Příklady použití volby -exec najdete v části PŘÍKLADY. Zadaný příkaz se spustí jednou pro každý odpovídající soubor. Příkaz se provede v počátečním adresáři. Kolem použití akce -exec jsou nevyhnutelné bezpečnostní problémy; místo toho byste měli použít volbu -execdir.

-exec příkaz {} +

Tato varianta akce -exec spustí zadaný příkaz na vybraných souborech, ale příkazový řádek je vytvořen připojením každého vybraného názvu souboru na konec; celkový počet vyvolání příkazu bude mnohem menší než počet odpovídajících souborů. Příkazový řádek je vytvořen v podstatě stejným způsobem, jakým xargs vytváří své příkazové řádky. V rámci příkazu je povolena pouze jedna instance `{}'. Příkaz se provede v počátečním adresáři.


Standardní ekvivalent find -iname ... -exec mv -t dest {} + pro find implementace, které nepodporují -iname nebo mv implementace, které nepodporují -t je použít shell ke změně pořadí argumentů:

find . -name '*.[cC][pP][pP]' -type f -exec sh -c '
  exec mv "[email protected]" /dest/dir/' sh {} +

Pomocí -name '*.[cC][pP][pP]' , také se při rozhodování o verzi c vyvarujeme spoléhání na aktuální národní prostředí nebo p .

Všimněte si, že + , na rozdíl od ; není speciální v žádném shellu, takže nemusí být uvozován (i když citace neuškodí, samozřejmě kromě shellů jako rc které nepodporují \ jako operátor citace).

Koncové / v /dest/dir/ je tak, že mv selže s chybou místo přejmenování foo.cpp na /dest/dir v případě, že pouze jeden cpp soubor byl nalezen a /dest/dir neexistoval nebo nebyl adresář (nebo symbolický odkaz na adresář).


Linux
  1. Jak Linux zpracovává více po sobě jdoucích oddělovačů cest (/home////username///soubor)?

  2. Bash =~ Regex A Https://regex101.com/?

  3. 12.04 Selhání instalace Grub-efi do /target/?

  1. „Nelze vytvořit adresář mezipaměti /home//.composer/cache/repo/https—packagist.org/, nebo adresář není zapisovatelný. Pokračovat bez mezipaměti“?

  2. Nainstalujte binární soubory do /bin, /sbin, /usr/bin a /usr/sbin, interakce s --prefix a DESTDIR

  3. Proč tento regulární výraz nefunguje na linuxu?

  1. Linux:Rozdíl mezi /dev/console, /dev/tty a /dev/tty0?

  2. Proč dávat věci jiné než /home do samostatného oddílu?

  3. Proč mají všechny adresáře /home, /usr, /var atd. stejné číslo inodu (2)?