GNU/Linux >> Znalost Linux >  >> Linux

Jak zobrazím názvy souborů, které obsahují dva znaky a jeden z nich je c?

Pomocí bash nastavte nastavení glob tak, aby chybějící shody nezpůsobily chybu:

shopt -u failglob  # avoid failure report (and discarding the whole line).
shopt -s nullglob  # remove (erase) non-matching globs.
ls ?c c?

Otazník je znak glob představující jeden znak. Protože chcete dvouznakové názvy souborů, jeden z nich musí být c , a je to buď první znak, nebo poslední znak.

S shopt -s dotglob tím by se také objevil soubor s názvem .c .

Pokud neexistují žádné odpovídající soubory, nastavení těchto možností shellu způsobí odstranění všech argumentů, což má za následek holý ls -- výchozí seznam čehokoli/všeho.

Místo toho použijte toto:

shopt -s nullglob  ## drop any missing globs
set -- ?c c?       ## populate the [email protected] array with (any) matches
if [ $# -gt 0 ]    ## if there are some, list them
  ls -d "[email protected]"
fi

Myslím, že lepší způsob je použít find :

find . -type f -name '*c*' -name '??'

To bude hledat rekurzivně. Chcete-li zobrazit pouze soubory v aktuálním adresáři:

find . ! -name . -prune  -type f -name '*c*' -name '??'

Pokud soubory existují (a neobsahují žádné speciální znaky jako \c ), můžete použít glob:

echo ?c c?

které budou odpovídat souborům, které mají jeden znak (? ) následovaný c nebo které mají c následovaný jedním znakem (? ).

Ale selže s názvy souborů které začínají pomlčkou jako -n nebo -e nebo se znaky zpětného lomítka jako \c nebo \n s echo jako oba -e a -n jsou speciální pro (některé shelly) echo a \c nebo \n by bylo interpretováno jako escape sekvence (\c ukončí výstup a \n vytiskne nový řádek, nikoli doslovné znaky \n v nějaké implementaci shellu echo a bash, když je volba shopt -s xpg_echo je nastaveno). Jiné aplikace nebo nástroje (jako ls ) bude mít některé další možnosti a může selhat u mnoha dalších spouštěných pomlčkou nebo interpretovat jiné znaky escape v názvech souborů.

Zobrazí také soubor s názvem cc dvakrát.

  • Pokud soubor může začínat pomlčkou (např. -n), použijte:

    $ ls -d -- ?n 
    -n 
    

    Nebo lépe:

    $ ls -d ./?n
    ./-n
    

Upozornění

  • Glob neodpovídá žádný soubor.

    1. Pokud soubory neexistují, globus nebude rozbalen a glob bude vytištěn v původní podobě.

      $ echo ?m m?
      ?m m?
      
    2. Kromě zsh.

      $ zsh -c 'echo ?m m?'
      zsh:1: no matches found: ./m?
      

      Shell se ukončí s chybou.
      Toto chování je řízeno nomatch Zsh možnost.

      $ zsh -c 'setopt +o nomatch; echo ?m m?'
      ?m m?
      

      Nebo:

      $ zsh -c 'echo ?m(N) m?(N)'
      ?m m?
      

      Ale to vypíše mm dvakrát.

    3. V bash můžete získat podobný výsledek jako zsh, pokud použijete volbu shellu failglob je nastaveno:

      $ bash -c 'shopt -s failglob; echo ?m m?'
      bash: no match: ?m
      

      Ale skript se nezastaví, shell se neukončí. Technicky vzato, řádek, kde se používá glob, se dále nespouští, ale provádění pokračuje na dalším řádku skriptu.

    4. V bash můžete nastavit volbu nullglob pro odstranění globů, které se neshodují:

      $ bash -c 'shopt -s nullglob; echo ?m m? done'
      done
      
  • Použití ls (podobně jako u jiných programů)

    1. S odpovídajícími soubory nebude žádný problém, ale bude také odpovídat (a vypíše) adresáře:

      $ ls ?c c?
      bc  cz  sc
      
      ac:
      hjk
      

      Raději použijte -d s ls (adresáře budou zahrnuty, ale nebudou rozšířeny).

      $ ls -d ?c c?
      ac bc cz sc
      
    2. Globy neodpovídají souboru (nebo adresáři)

      Poté ls ohlásí poruchu

      $ ls ?m m?
      ls: cannot access '?m': No such file or directory
      

      Jiné programy možná (pravděpodobně) ne proveďte podobné kontroly.

    3. Pomocí nullglob s bash dá prázdný seznam ls, takže vypíše obsah nebo pwd, jako by jen ls byl proveden:

      $ ls ?m m?
      ac a.out cz 3 b sc ab bc
      

      Tomu by se dalo předejít pomocí ./

      $ ls -d ./?m ./m?
      ls: cannot access './?m': No such file or directory
      ls: cannot access './m?': No such file or directory
      

Nebo můžete použít regex find (ale bude procházet podadresáře s prune chybí) (Upozorňujeme, že toto nebude opakovat soubor s názvem cc):

    $ find . ! -name . -prune -regex '.*/\(.c\|c.\)'
    ./ac
    ./cc
    ./sc
    ./bc
    ./cz

Linux
  1. `^m` A jak se toho zbavit?

  2. Jak zobrazit zvýraznění syntaxe v souboru?

  3. Rsync dva typy souborů v jednom příkazu?

  1. Jak vyprázdnit (zkrátit) soubor na linuxu, který již existuje a je nějakým způsobem chráněn?

  2. Jak spojit více řádků názvů souborů do jednoho s vlastním oddělovačem?

  3. Jak se dotknout souboru a mkdir v případě potřeby na jednom řádku

  1. AWK a názvy souborů s mezerou.

  2. Ocas a zástupné znaky

  3. Jak získat řádky, které obsahují řetězec v souboru?