xargs
si aspetta un formato di input molto speciale in cui gli argomenti sono delimitati da spazi vuoti o newline (a volte altre forme di spazi bianchi verticali, a volte dipendenti dalla locale corrente), e dove è possibile usare una virgoletta singola, virgolette doppie e una barra rovesciata (ma in un modo diverso dalle citazioni di shell).
-l1
non è passare una riga di input come un singolo argomento a mkdir
, ma chiamare una chiamata mkdir
per ogni singola riga di input ma con parole su quella riga ancora separate come argomenti diversi mkdir
.
L'implementazione GNU ha xargs
aggiunto -0
un'opzione decenni fa per accettare input delimitati da NUL. Questo è il modo più ovvio per separare le parole che finiranno per essere argomenti di un comando perché il carattere NUL è l'unico carattere che non può comparire in un argomento di comando o in un nome di file (il formato dell'elenco scelto che inserisce un file per riga non può rappresentare tutti i nomi file possibili in quanto non consente una nuova riga in un nome file).
Questo -0
è stato copiato da molte altre xargs
implementazioni, ma non da tutte.
Con quelli che puoi fare:
<file tr '\n' '\0' | xargs -0 mkdir -p --
Ciò chiamerà il mkdir
minor numero di volte possibile con il maggior numero di argomenti possibile.
Ma nota che se file
è vuoto, mkdir
verrà comunque eseguito e otterrai un errore di sintassi a mkdir
causa dell'argomento mancante. GNU ha xargs
aggiunto -r
un'opzione per ciò che è stato copiato da alcune altre implementazioni.
GNU ha xargs
anche aggiunto (in seguito) -d
un'opzione per poter specificare delimitatori arbitrari, ma non credo che nessun'altra implementazione lo abbia copiato. Con GNU xargs
, il modo migliore è con:
xargs -rd '\n' -a file mkdir -p --
Passando il file con -a
(anche un'estensione GNU) invece di stdin, ciò significa che lo mkdir
stdin viene preservato.
POSIX, dovresti post-elaborare l'input per metterlo nel formato previsto da xargs
. Potresti farlo ad esempio con:
<file sed 's/"/"\\""/g; s/^/"/; s/$/"/' | xargs mkdir -p --
Dove racchiudiamo ogni riga tra virgolette doppie e fuggiamo da ciascuna "
come "\""
prima di alimentare xargs.
Ma attenzione alle possibili limitazioni:
- l'errore quando il file è vuoto già menzionato sopra
- potrebbe non riuscire con alcune implementazioni (incluso di
sed
) se il contenuto di file
non è un testo valido nella locale corrente. Se file
contiene nomi di file che codificano in più di un set di caratteri diverso o un set di caratteri diverso da quello della locale, è possibile correggere la locale su C, che dovrebbe essere d'aiuto.
- alcune
xargs
implementazioni hanno limiti ridicolmente bassi sulla lunghezza massima di un argomento (possono arrivare a 255 byte).
Per aggirare l' errore di sintassi in caso di errore di input vuoto , è possibile scrivere:
<file sed 's/"/"\\""/g; s/^/"/; s/$/"/' |
xargs sh -c '[ "$#" -eq 0 ] || exec mkdir -p -- "$@"' sh
-d
opzione sono necessari xarg GNU .