GNU/Linux >> Znalost Linux >  >> Linux

Rozšíření cesty Bash/shell pro Mkdir, Touch atd?

Takže udělat něco takového v bash a většina ostatních shellů nebude fungovat při vytváření více podadresářů nebo souborů v podadresářích…

mkdir */test
touch */hello.txt
 

Samozřejmě existuje mnoho způsobů, jak to skutečně udělat, já preferuji použití find pokud je to možné, místo použití for smyčka, hlavně kvůli čitelnosti.

Ale moje otázka zní, proč výše uvedené nefunguje?
Z toho, co jsem pochopil, je to proto, že úplný cílový soubor/cesta neexistuje, ale určitě je to dobrá věc, když se snažím mkdir nebo touch . Vždy jsem se jen posunul dál a nikdy jsem to nezpochybňoval.
Ale má pro to někdo slušné vysvětlení, které mi pomůže to jednou provždy pochopit?

Přijatá odpověď:

Bod, který vám možná uniká – se kterým má mnoho lidí potíže,
zvláště pokud mají zkušenosti s jinými operačními systémy, než přijdou na *nix
– je to, že v mnoha jiných operačních systémech jsou zástupné znaky na příkazového řádku se normálně předávají příkazu zpracovat, jak uzná za vhodné. Například v příkazovém řádku systému Windows

rename *.jpeg *.jpg
 

Zatímco v *nix, za účelem zjednodušení práce
programátorů jednotlivých příkazů (např. mv ), zástupné znaky
(pokud nejsou uvozovány nebo escapovány) zpracovává shell
způsobem, který je nezávislý na rozhraní a funkčnosti
příkazu, jehož jsou zástupné znaky argumenty.
Většina programů, které berou názvy souborů jako argumenty příkazového řádku, očekává existenci těchto souborů
(ano, mkdir a touch jsou výjimky z tohoto pravidla,
stejně jako mkfifo , mknod a v částečné míře cp , ln , mv a rename;
a pravděpodobně existují další),
, takže ve skutečnosti nemá smysl, aby shell rozšiřoval zástupné znaky
na názvy souborů, které neexistují.
A pro shell (a tím myslím každý shell –
Bourne, bash, csh, fish, ksh, zsh, atd...) zacházet s výjimkami jinak
by byl pravděpodobně příliš velký problém.

To znamená, že existuje několik způsobů, jak dosáhnout výsledku, jaký chcete.
Pokud víte, na co se zástupný znak rozšíří,
a není dlouhý, můžete jej vygenerovat pomocí rozšíření složené závorky:

touch {red,orange,yellow,green,blue,indigo,violet}/rgb.txt
 

Obecnější řešení:

sh -c 'for arg do mkdir -- "$arg"/test; done' -- *
 

Gilles mi pomohl najít jiný způsob
, jak to udělat v bash.

benbradley=(*)
mkdir "${benbradley[@]/%//test}"
 

Zřejmě benbradley je zde pouze identifikátor; můžete použít libovolné jméno
(např. libovolné písmeno).
Trvalo mi několik pokusů, než jsem to udělal správně, tak mi to dovolte rozebrat:

  • identifier=value vytvoří (skalární) proměnnou s názvem identifier (pokud již neexistuje) a přiřadí hodnotu value k tomu.
    Například G=Man .
    Na skalární proměnnou můžete odkazovat pomocí $identifier;
    například $G , nebo bezpečněji jako ${identifier} .
    Například $Gage a $Gilla může být nedefinováno,
    ale ${G}age je Manage a ${G}illa je Manilla .
  • identifier=(value1 value2) vytvoří proměnnou pole s názvem identifier (pokud již neexistuje) a přiřadí mu uvedené hodnoty.
    Například
    spektrum=(červená oranžová žlutá zelená modrá indigová fialová)

    nebo

      all_text_files=(*.txt)

      $name bude odkazovat na první prvek (a je tedy docela k ničemu).
      Na libovolný prvek můžete odkazovat jako ${name[subscript]};
      například ${spectrum[0]} je red a ${spectrum[4]} je blue .
      A můžete použít ${name[@]} a ${name[*]} odkazovat na celé pole.

      Související:iPod touch byl ukraden a potřebuje najít?

      Takže tady je to po částech:

        " ${ benbradley[@] / % / /test } "
        • ${parameter/pattern/string} rozšiřuje ${parameter} a nahradí nejdelší shodu
          z pattern s string .
        • Pokud pattern začíná # ,
          musí se shodovat na začátku rozšířené hodnoty parameter .
          Pokud pattern začíná % ,
          musí se shodovat na konci rozšířené hodnoty parameter .
          Jinými slovy,
          % (zbytek_vzoru)

          chová se jako

            (the-rest_of_the_regulex) $ 

            (ano, to se zdá trochu obráceně).
            Takže pattern to je jen % je jako regulární výraz, který je pouze $
            odpovídá konci vstupního řetězce (vyhledávací mezera).

            • A já používám string z /test .
              Takže toto nahradí konec parametru /test (tj. připojí se /test na parametr).
            • Další věc o ${parameter/pattern/string} to není intuitivní, je to vždy končí } .
              Nemusí a nemůže , končí třetím / .
              Proto / v string nelze interpretovat jako oddělovač,
              a proto můžeme mít string z /test aniž byste museli escapovat / .
            • Pokud parameter je proměnná pole
              s indexem @ nebo * ,
              operace substituce se postupně aplikuje na každý člen pole.
            • Když na pole odkazujete jako ${name[@]} (spíše než ${name[*]} ) a výsledky vložte do dvojitých uvozovek,
              zachováte integritu prvků pole
              (tj. zachováte v nich mezery a další speciální znaky)
              aniž byste jednotlivé prvky slučovali do jedno dlouhé slovo.

            Linux
            1. Přizpůsobení prostředí Bash

            2. Jak vytvořit prostředí Clean Shell pro dočasné použití?

            3. 12 Bash pro příklady smyček pro vaše skriptování prostředí Linux

            1. Jak zakázat automatické dokončování (dokončování karet) v bash shell

            2. Bash skript:Použití příkazu script z bash skriptu pro protokolování relace

            3. Bash Shell Script - Zkontrolujte, zda nemáte příznak a zjistěte jeho hodnotu

            1. Jaký je váš oblíbený shell pro práci správce systému?

            2. Proč má uživatel mysql bash shell v /etc/passwd?

            3. Odůvodnění Bash Shell vás nevaruje před aritmetickým přetečením atd.?