GNU/Linux >> Znalost Linux >  >> Linux

Jak analyzuji výstup příkazu find, když názvy souborů obsahují mezery?

V ideálním případě to tak neděláte vůbec, protože správně analyzovat názvy souborů ve skriptu shellu je vždy obtížné (opravte mezery, stále budete mít problémy s jinými vloženými znaky, zejména s novým řádkem). Toto je dokonce uvedeno jako první položka na stránce BashPitfalls.

To znamená, že existuje způsob, jak téměř dělat to, co chcete:

oIFS=$IFS
IFS=$'\n'

find . -name '*.txt' | while read -r i; do
  # use "$i" with whatever you're doing
done

IFS=$oIFS

Nezapomeňte také uvést $i při jeho používání, aby se předešlo dalšímu výkladu mezer později. Nezapomeňte také nastavit $IFS zpět po jeho použití, protože pokud tak neučiníte, způsobí to později matoucí chyby.

K tomu je připojeno ještě jedno upozornění:co se děje uvnitř while smyčka se může odehrávat v podskořápce v závislosti na přesném prostředí, které používáte, takže nastavení proměnných nemusí přetrvávat. for smyčková verze se tomu vyhýbá, ale za cenu, že i když použijete $IFS řešení, abyste se vyhnuli problémům s mezerami, budete mít potíže, pokud find vrací příliš mnoho souborů.

V určitém okamžiku se správnou opravou pro toto vše stane provádění v jazyce, jako je Perl nebo Python místo shellu.


Použijte find -print0 a přesuňte jej na xargs -0 , nebo napište svůj vlastní malý program v C a přeneste ho do svého malého programu v C. To je to, co -print0 a -0 byly vynalezeny pro.

Shell skripty nejsou nejlepší způsob, jak zacházet s názvy souborů s mezerami:můžete to udělat, ale je to neohrabané.


Můžete nastavit "vnitřní oddělovač polí" (IFS ) na něco jiného než prostor pro rozdělení argumentu smyčky, např.

ORIGIFS=${IFS}
NL='
'
IFS=${NL}
for i in $(find . -name '*.txt'); do
    IFS=${ORIGIFS}
    #do stuff
done
IFS=${ORIGIFS}

Resetoval jsem IFS po jeho použití v nálezu, většinou proto, že vypadá hezky, myslím. Nezaznamenal jsem žádné problémy s nastavením na nový řádek, ale myslím, že je to "čistší".

Další metoda, v závislosti na tom, co chcete dělat s výstupem z find , je buď přímo použít -exec s find nebo použijte -print0 a potrubím do xargs -0 . V prvním případě find postará se o escapování názvu souboru. V -print0 případ, find vytiskne svůj výstup s oddělovačem null a poté xargs se v tomto rozchází. Protože žádný název souboru nemůže obsahovat tento znak (co já vím), je to také vždy bezpečné. To je většinou užitečné v jednoduchých případech; a obvykle není skvělou náhradou za úplné for smyčka.


Linux
  1. Jak zjistit, co dělá příkaz Linuxu

  2. Jak auditovat oprávnění pomocí příkazu find

  3. Jak přiřadit výstup příkazu proměnné shellu?

  1. Jak zastavit příkaz Najít po prvním zápase?

  2. Jaký je rozdíl mezi příkazem locate a find v Linuxu

  3. Co znamená symbol linux pipe | dělat?

  1. Jak zjistit, jakou verzi OS X používám z příkazového řádku?

  2. Jak číst sloupec IDLE ve výstupu příkazu Linux 'w'?

  3. Jaká je správná syntaxe find -exec