Sto cercando di scrivere uno script che prenda un .txt nome di file come argomento, legga la riga del file per riga e passa ogni riga a un comando. Ad esempio, esegue command --option "LINE 1", quindi command --option "LINE 2" e così via. Loutput del comando viene scritto in un altro file. Come posso farlo? Non so da dove iniziare. 
Risposta
 Utilizza il while read loop: 
: > another_file ## Truncate file. while IFS= read -r LINE; do command --option "$LINE" >> another_file done < file 
Un altro è reindirizzare loutput per blocco:
while IFS= read -r LINE; do command --option "$LINE" done < file > another_file 
Lultimo è aprire il file:
exec 4> another_file while IFS= read -r LINE; do command --option "$LINE" >&4 echo xyz ## Another optional command that sends output to stdout. done < file 
 Se uno dei comandi legge linput, sarebbe un buon idea di usare un altro fd per linput in modo che i comandi non lo mangino (qui assumendo ksh, zsh o bash per -u 3, utilizza <&3 invece portabile): 
while IFS= read -ru 3 LINE; do ... done 3< file 
Fin alleato per accettare argomenti, puoi fare:
#!/bin/bash FILE=$1 ANOTHER_FILE=$2 exec 4> "$ANOTHER_FILE" while IFS= read -ru 3 LINE; do command --option "$LINE" >&4 done 3< "$FILE" 
Quale potrebbe essere eseguito come:
bash script.sh file another_file 
 Idea extra. Con bash, utilizza readarray: 
readarray -t LINES < "$FILE" for LINE in "${LINES[@]}"; do ... done 
 Nota: IFS= può essere omesso se non ti dispiace che i valori di riga vengano tagliati dagli spazi iniziali e finali. 
Risposta
 Unaltra opzione è xargs. 
 Con GNU xargs: 
xargs -a file -I{} -d"\n" command --option {} other args 
 {} è il segnaposto per la riga di testo. 
 Altro xargs generalmente non” t hanno -a, -d, ma alcuni hanno -0 per input delimitato da NUL. Con quelli, puoi fare: 
< file tr "\n" "\0" | xargs -0 -I{} command --option {} other args 
 Su sistemi conformi a Unix (-I è opzionale in POSIX e solo richiesto per i sistemi conformi a UNIX), devi preelaborare linput per  citare  le righe nel formato previsto da xargs: 
< file sed "s/"/"\\""/g;s/.*/"&"/" | xargs -E "" -I{} command --option {} other args 
 Tuttavia, tieni presente che alcune xargs implementazioni hanno un limite molto basso sulla dimensione massima dellargomento (255 su Solaris, ad esempio, il minimo consentito dalla specifica Unix). 
Commenti
Risposta
Mantenendo la precisione alla domanda:
#!/bin/bash # xargs -n param sets how many lines from the input to send to the command # Call command once per line [[ -f $1 ]] && cat $1 | xargs -n1 command --option # Call command with 2 lines as args, such as an openvpn password file # [[ -f $1 ]] && cat $1 | xargs -n2 command --option # Call command with all lines as args # [[ -f $1 ]] && cat $1 | xargs command --option 
Commenti
- ha funzionato come un fascino 🙂
 - +1 mi è piaciuto molto, grazie
 
Risposta
La migliore risposta che ho trovato und è:
for i in `cat`; do "$cmd" "$i"; done < $file 
EDIT:
… quattro anni dopo …
dopo diversi voti negativi e un po di esperienza in più, ti consiglio quanto segue ora:
xargs -l COMMAND < file 
Commenti
-  Questo richiamerà il comando una volta per ogni  parola  nel file. Inoltre, dovresti sempre citare i riferimenti alle variabili di shell (come in 
do "$cmd" "$i";) a meno che tu non abbia un motivo per non farlo; se il file conteneva un*come parola da solo, il codice verrebbe eseguito$cmd *, che, ovviamente, eseguirà il comando con un elenco dei file nella directory corrente. -  @ G-Man, tranne in 
zsh,`cat`espanderebbe già il*(il$inon quotato potrebbe ancora espandere un carattere jolly (un secondo round) se lespansione di`cat`ne introduce alcuni). In ogni caso, questo approccio è davvero sbagliato. - +1. Funzionerà bene, se ogni riga contiene solo linput necessario per il comando utilizzato senza spazi.
 - +1, è piaciuta la soluzione xargs
 -  Funziona! (la modifica successiva 
xargs -l COMMAND < file). Grazie! 
Risposta
 sed "s/"/"\\\\""/g;s/.*/\$* "&"/" <<\FILE |\ sh -s -- command echo --option all of the{&}se li$n\es "are safely shell quoted and handed to command as its last argument following --option, and, here, before that echo FILE 
OUTPUT
--option all of the{&}se li$n\es "are safely shell --option quoted and handed to command as its last argument --option following --option, and, here, before that echo 
Risposta
ed file.txt %g/^/s// / 2,$g/^/-,.j 1s/^/command/ wq chmod 755 file.txt ./file.txt 
Prendi tutte le righe di un file e passarle come argomenti a un singolo comando, ad esempio
command line1 line2 line3 .... 
 Se è necessario --option flag per precedere ogni riga modificare il secondo comando in: 
%g/^/s// --option / 
Commenti
- What -1 for usando ed … davvero?
 -  Non ‘ ti ho votato in modo negativo, ma la persona che lha fatto aveva probabilmente questi motivi: (1) Questo non funziona cosa chiede la domanda. Questo richiama il comando una volta con tutto il contenuto del file sulla riga di comando; anziché  una volta per riga .(2) Questo non fa nulla per gestire i caratteri che sono speciali per la shell (che potrebbero essere nel file); ad es. 
',",<,>,;, ecc. (3) Questo crea un file temporaneo non necessario. (4) Cose come questa vengono generalmente fatte con i “documenti qui”. (5) I tuoi comandiedsono goffi; i primi due comandi possono essere ridotti a%s/^/ /e%j. 
<file xargs -L 1 -I{} command --option {} other args