So di poter risolvere questo problema in diversi modi, ma mi chiedo se esiste un modo per farlo utilizzando solo bash built-in e, in caso contrario, qual è il modo più efficiente per farlo.
Ho un file con contenuti come
AAA
B C DDD
FOO BAR
con questo intendo solo che ha più righe e ogni riga può avere o meno spazi. Voglio eseguire un comando come
cmd AAA "B C DDD" "FOO BAR"
Se utilizzo cmd $(< file)
ottengo
cmd AAA B C DDD FOO BAR
e se uso cmd "$(< file)"
ottengo
cmd "AAA B C DDD FOO BAR"
Come posso ottenere che ogni riga venga trattata esattamente come un parametro?
Risposta accettata:
Portatile:
set -f # turn off globbing
IFS='
' # split at newlines only
cmd $(cat <file)
unset IFS
set +f
Oppure usando una subshell per creare l'IFS
e l'opzione cambia in locale:
( set -f; IFS='
'; exec cmd $(cat <file) )
La shell esegue la suddivisione dei campi e la generazione di nomi di file sul risultato di una sostituzione di una variabile o di un comando che non è racchiusa tra virgolette. Quindi devi disattivare la generazione del nome file con set -f
e configura la suddivisione dei campi con IFS
per fare in modo che solo le nuove righe separino i campi.
Non c'è molto da guadagnare con i costrutti bash o ksh. Puoi creare IFS
locale a una funzione, ma non set -f
.
In bash o ksh93, puoi archiviare i campi in un array, se devi passarli a più comandi. È necessario controllare l'espansione nel momento in cui si costruisce l'array. Quindi "${a[@]}"
si espande agli elementi dell'array, uno per parola.
set -f; IFS=$'n'
a=($(cat <file))
set +f; unset IFS
cmd "${a[@]}"