/ / Nastavenie premenných shellu tak, aby obsahovali zoznamy súborov - bash, shell

Nastavenie premenných shellu tak, aby obsahovali zoznamy súborov - bash, shell

Nasledujúci kód používam na nastavenie apremenná obsahujúca sériu rôznych mien súborov, ktoré potom následne vykonám na niektorých funkciách. Príslušné súbory sa nachádzajú v inom adresári (DIRECTORY) do adresára, kde sa kód vykonáva (CURRENT_DIRECTORY). Myslel som si, že nasledujúci kód je možné použiť na zmenu do adresára obsahujúceho súbory cd $DIRECTORY, uloží zoznam súborov do premennej $FILES a potom sa vráťte späť do pôvodného adresára (cd $CURRENT_DIRECTORY) kde je možné vykonať zvyšok kódu. Ak však urobím dva príkazy ozveny, prvý obsahuje zoznam súborov, keď sa nachádzam v adresári, kde sú uložené súbory, ale druhý príkaz echo iba vytlačí "vclist_2d_*.txt", tj. interpretuje to ako reťazec a nie ako zoznam súborov (pravdepodobne preto, že som sa zmenil späť do pôvodného adresára, a preto nemôže nájsť žiadne súbory, ktoré sa zhodujú vclist_2d_*.txt). Prečo sa to stane a ako môžem vyriešiť tento problém (bez spustenia všetkého v rovnakom adresári)?

#!/bin/bash
CURRENT_DIRECTORY=`pwd`
DIRECTORY=/home/Documents/NewDirectory/

cd $DIRECTORY
pwd
FILES=vclist_2d_*.txt
echo $FILES
cd $CURRENT_DIRECTORY
echo $FILES

odpovede:

4 pre odpoveď č. 1

Musíte si uložiť výsledok globálnej expanzie.

Globy sa nerozširujú v jednoduchých priradeniach premenných, takže váš súčasný kód rozširuje globus, keď vy echo to (čo je dôvod, prečo dosiahnete správanie, ktoré vidíte). Vyskúšajte echo "$FILES" a napríklad sa vôbec nerozšíri.

Priradenie k poliam sa však rozširuje FILES=(vclist_2d_*.txt) okamžite rozšíri glob a potom použije echo "${FILES[@]}" neskôr bude fungovať správne.


1 pre odpoveď č. 2

FILES=vclist_2d_*.txt sa nerozbalí o shell. FILES teraz obsahuje reťazec vclist_2d_*.txt.

echo $FILES odošle echo vclist_2d_*.txt do ulity. Škrupina potom rozšíri vzor, ​​výsledkom čoho je buď A) reťazec vclist_2d_*.txt ak sa vzor nezhoduje s ničím, alebo B) zoznam zodpovedajúcich názvov súborov.

Potom zmeníte adresár a postup zopakujete. Zoznam súborov nie je v žiadnom okamihu priradený k žiadnej premennej.

Teraz ty mohol priradiť výkon z echo vclist_2d_*.txt do premennej (SOMEVAR=$(echo vclist_2d_*.txt), ale to by váš problém vyriešilo iba do polovice. Ako zamýšľate „konať s každým súborom v zozname“? Ak uvažujete o a for file in $SOMEVAR, zvážte, čo by sa stalo, keby názov súboru obsahoval medzeru ...

Najjednoduchším a najrobustnejším riešením je použitie find miesto:

find $DIRECTORY -name "vclist_2d_*.txt" -exec do_something {} +

Výsledkom je do_something prešiel zoznam zodpovedajúcich súborov. Ak je zoznam veľmi dlho, to môže byť rozdelené do niekoľkých hovorov z do_something.

find $DIRECTORY -name "vclist_2d_*.txt" -exec do_something {} ;

Výsledkom je do_something sa volá pre každý zhodný súbor.

Ak existuje šanca, že váš prúd adresár môže obsahovať súbory zodpovedajúce vzoru odovzdanému find vyššie, musíte uniknúť z hviezdičky (pridaním úvodzoviek, ako som to urobil ja, alebo únikom cez *) aby ste zabránili rozšíreniu shellu tým, že find rozkaz do niečoho iného.