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).
-l1non è passare una riga di input come un singolo argomento a mkdir, ma chiamare una chiamata mkdirper ogni singola riga di input ma con parole su quella riga ancora separate come argomenti diversi mkdir.
L'implementazione GNU ha xargsaggiunto -0un'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 xargsimplementazioni, ma non da tutte.
Con quelli che puoi fare:
<file tr '\n' '\0' | xargs -0 mkdir -p --
Ciò chiamerà il mkdirminor numero di volte possibile con il maggior numero di argomenti possibile.
Ma nota che se fileè vuoto, mkdirverrà comunque eseguito e otterrai un errore di sintassi a mkdircausa dell'argomento mancante. GNU ha xargsaggiunto -run'opzione per ciò che è stato copiato da alcune altre implementazioni.
GNU ha xargsanche aggiunto (in seguito) -dun'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 mkdirstdin 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 filenon è un testo valido nella locale corrente. Se filecontiene 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
xargsimplementazioni 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
-dopzione sono necessari xarg GNU .