GNU/Linux >> Znalost Linux >  >> Ubuntu

Jste zmateni Grepem a zástupným znakem *?

Spouštím následující příkaz, abych našel všechny soubory/adresáře, které nemají nic společného s „flash_drive_data“:

find . -not -path './flash_drive_data*' | grep "./*flash*"

Je několik věcí, které jsem zkoušel a které mě mate:

1. Když spustím výše uvedený příkaz, dostanu několik „částečných“ zásahů (tj. zcela neodpovídají *flash* vzor. Například:

./.local/lib/python3.7/site-packages/jedi/third_party/typeshed/third_party/2and3/flask
./.local/lib/python3.7/site-packages/jedi/third_party/typeshed/third_party/2and3/flask/cli.pyi
./.local/lib/python3.7/site-packages/jedi/third_party/typeshed/third_party/2and3/flask/signals.pyi
./.local/lib/python3.7/site-packages/jedi/third_party/typeshed/third_party/2and3/flask/templating.pyi
./.local/lib/python3.7/site-packages/jedi/third_party/typeshed/third_party/2and3/flask/sessions.pyi
./.local/lib/python3.7/site-packages/jedi/third_party/typeshed/third_party/2and3/flask/json
./.local/lib/python3.7/site-packages/jedi/third_party/typeshed/third_party/2and3/flask/json/tag.pyi

3/flas na konci je zvýrazněno.

2. Když jsem nahradil grep "*flash*" pouze pomocí grep "*" , Očekával jsem, že se mi všechny soubory vrátí hledáním, ale nedostal jsem žádný. Proč? Potom, když jsem udělal grep "**" Věřím, že jsem dostal všechny soubory (nebo si alespoň myslím, že ano). Znovu, proč tomu tak je?

3. Konečně, cílem toho, co jsem dělal výše, bylo zajistit, že když jsem spustil find . -not -path './flash_drive_data*' Nedostal jsem nic souvisejícího s flash_drive_data. Zdálo se, že jsem to udělal (s nějakým neočekávaným chováním s grep, jak jsem vysvětlil výše). Když jsem však spustil:
find . -not -path './flash_drive_data*' -exec tar cfv home.tar.bz '{}' +

Dostával jsem výstup včetně věcí jako:

./flash_drive_data/index2/ask-sdk-core/dist/dispatcher/error/handler/

takže byly zahrnuty soubory flash_drive_data.

Přijatá odpověď:

find . -not -path './flash_drive_data*' | grep "./*flash*"

Jde o to, že grep používá regulární výrazy, zatímco find -path používá shody vzoru stylu shell glob. Hvězdička má v těchto dvou odlišných význam.

Regulární výraz ./*flash* odpovídá nejprve libovolnému znaku (. ), pak nula nebo více lomítek (/* ), pak doslovný řetězec flas , pak libovolné číslo (nula nebo více) z h znaky. 3/flas odpovídá tomu (s nulou krát h ), a stejně tak např. reflash (s nulou krát / ).

Stačí použít grep flash místo toho, vzhledem k tomu, že se shoduje kdekoli ve vstupu, takže úvodní a koncové části „shoda s čímkoli“ jsou zbytečné.

Nebo použijte find -path './*flash*' -and -not -path './flash_drive_data*'

Když jsem nahradil grep "*flash*" pouze pomocí grep "*" , mám [žádné shody].

Protože hvězdička znamená „libovolné číslo předchozího atomu“, není zde opravdu dobře definována. grep interpretuje to jako doslovnou hvězdičku, ale ve skutečnosti by to měla být chyba.

Když jsem však spustil:find . -not -path './flash_drive_data*' -exec tar cfv home.tar.bz '{}' + Dostával jsem výstup včetně věcí jako:

./flash_drive_data/index2/ask-sdk-core/dist/dispatcher/error/handler/

tedy flash_drive_data soubory byly zahrnuty.

Všimněte si, že tar ukládá soubory rekurzivně a první výstup toho find je . pro aktuální adresář, takže vše bude uloženo. Možná budete chtít použít ! -type d pomocí find chcete-li vyloučit adresáře z výstupu, nebo (lépe) se podívejte na -exclude=PATTERN možnosti tar .


Ubuntu
  1. Najděte soubory a adresáře v Linuxu pomocí příkazu find

  2. Najděte MAC adresu v Ubuntu 21.10

  3. Grep pro více řetězců v souborech a pak seznam souborů v pořadí velikosti?

  1. Řez / Grep A Df -h?

  2. Grep And Tail -f?

  3. Najít pouze první výskyt pouze pomocí Grepu?

  1. Použití grep a sed k nalezení a nahrazení řetězce

  2. Jaký je rozdíl mezi „vyhledat“ a „najít“ v Linuxu?

  3. Jak zjistit informace o RAM?