Je možné „rozdělit“ výpis adresáře – řekněme do bloků nějakého čísla, provádět různé akce na každém „rozsahu“?
Řekněme například, že mám v jiné složce následující adresáře:
$ ls test
abc/
def/
hij/
klm/
nop/
qrs/
tuv/
wxy/
zzz/
A chci provést nějakou akci na prvních 3 adresářích, další na druhých 3 a tak dále.
Myslel jsem si, že by možná fungovala smyčka napříč čísly na základě výstupu něčeho jako ls | nl
(ale než to někdo zmíní, vím, že analyzuji ls
je ne-ne!)
To samozřejmě nefunguje, ale doufám, že ilustruje můj názor:
for dir in `ls | nl`;
do
do-something-with ${dir{1..3}} # Where $dir has taken on some numerical value linked to the folder)
do-something-with ${dir{4..6}}
# And so on...
do-something-with ${dir{n-3..n}}
done
Se složkami, se kterými to mám v úmyslu skutečně udělat, lze pracovat v libovolném pořadí (tj. konečné rozdělení může být zcela libovolné), ale nemají žádnou logickou konzistenci pojmenování – tím chci říct, že je nelze rozumně uspořádat podle abecedy nebo čísel na základě libovolného klíče v rámci samotného názvu adresáře.
Přijatá odpověď:
Není důvod dělat některou z následujících chyb pro tuto situaci:
- Používejte nepřenosná rozšíření GNU (například
xargs -0
) - Analyzujte názvy souborů pouze jako proud textu a předstírejte, že nemůžou obsahovat nové řádky.
Přenosně to zvládnete bez větších potíží:
set -- */
while [ "$#" -gt 0 ]; do
case "$#" in
1)
my-command "$1"
shift 1
;;
2)
my-command "$1" "$2"
shift 2
;;
*)
my-command "$1" "$2" "$3"
shift 3
;;
esac
done
Opravdu je to podrobnější, než je nutné, ale je to takto čitelné.
Pro jiný typ dělení, kde chcete rozdělit všechny adresáře přesně na tři různé způsoby zpracování (ale nemusíte je zpracovávat současně), můžete to udělat takto:
x=1
for d in *; do
[ ! -d "$d" ] && continue
case "$x" in
1)
# do stuff with "$d"
;;
2)
# do stuff with "$d"
;;
3)
# do stuff with "$d"
;;
esac
x=$(($x+1))
[ "$x" -eq 4 ] && x=1
done