it-swarm-eu.dev

Ve skriptu bash Shell píšete smyčku for, která iteruje přes hodnoty řetězce

V bashu vím, že je možné napsat smyčku for, ve které se některá řídicí proměnná smyčky i iteruje přes zadaná celá čísla. Například mohu napsat skript bash Shell, který vytiskne celá čísla mezi 1 a 10:

#!/bin/bash

for i in {1..10}
do
 echo $i
done

Je možné místo toho iterovat přes regulační proměnnou smyčky, která je řetězcem, pokud uvedu seznam řetězců? Předpokládejme například, že mám řetězec fname, který představuje název souboru. Chci zavolat sadu příkazů pro každý název souboru. Například bych mohl chtít vytisknout obsah fname pomocí příkazu, jako je tento:

#!/bin/bash

for fname in {"a.txt", "b.txt", "c.txt"}
do
 echo $fname
done

Jinými slovy, při první iteraci by fname měla mít hodnotu fname="a.txt", zatímco při druhé iteraci by fname měla mít hodnotu fname="b.txt", a tak dále. Bohužel se zdá, že výše uvedená syntaxe není zcela správná. Chtěl bych získat výstup:

a.txt

b.txt

c.txt

ale když vyzkouším výše uvedený kód, získám tento výstup:

{a.txt,

b.txt,

c.txt}

Můžete mi prosím pomoci určit správnou syntaxi, abych mohl iterativně změnit hodnotu/obsah proměnné fname? Děkuji vám za Váš čas.

25
Andrew

Správná syntaxe je následující:

#!/bin/bash

for fname in a.txt b.txt c.txt
do
  echo $fname
done
39
Ali Gangji

Vypadá to, že byste měli udělat ...

printf %s.txt\\n a b c
1
mikeserv

Jak poznamenal uživatel13742 v comments , můžeme použít pole v bash a ksh:

#!/usr/bin/env bash

files_list=( "a.txt" "b.txt" "c and space.txt" )

for i in "${files_list[@]}"
do
    echo "$i"
    # do something else here,maybe
done

A funguje tak:

$ ./iterate_files_array.sh                                                      
a.txt
b.txt
c and space.txt

Některé skořápky, například dash (/bin/sh na Ubuntu) nepodporují pole. V takovém případě bychom se mohli uchýlit k použití struktury zde-dokumentu: <<

#!/bin/sh

while IFS= read -r line
do
    echo "$line"
done << EOL
one.txt
two.txt
with space.txt
EOL
0