Quanto segue dovrebbe funzionare su qualsiasi percorso.
Dichiara una funzione per poter utilizzare head
e tail
sull'output separato da NUL:
nul_terminated() {
tr '\0\n' '\n\0' | "[email protected]" | tr '\0\n' '\n\0'
}
Quindi puoi usarlo per ottenere un elenco di percorsi separati da NUL dalla tua ricerca dopo aver attraversato tail
:
find . -exec printf '%s\0' {} \; | nul_terminated tail -n 2
Puoi quindi reindirizzarlo a xargs
e aggiungi le tue opzioni:
find . -iname "*FooBar*" -exec printf '%s\0' {} \; | nul_terminated tail -n 2 | xargs -I "{}" -0 cp "{}" "dest"
Spiegazione:
find
file nella directory corrente (.
) e sotto con un nome contenentefoobar
(senza distinzione tra maiuscole e minuscole a causa deli
in-iname
);- per ogni file, esegui (
-exec
) un comando a - stampa ogni percorso di file (
{}
) seguito da un carattere NUL (\0
) individualmente (\;
); - scambia le nuove righe e i caratteri NUL (
tr '\0\n' '\n\0'
);" - ottieni le ultime due righe (ovvero i percorsi;
tail -n 2
,"[email protected]"
); - scambia di nuovo le nuove righe e i caratteri NUL per ottenere un elenco di nomi di file separati da NUL (
tr '\0\n' '\n\0'
).
Il xargs
comando è un po' più difficile da spiegare. Costruisce altrettanti cp ... "dest"
comandi necessari per rientrare nella lunghezza massima del comando del sistema operativo, sostituendo il {}
token nel comando con il nome effettivo del file (-I "{}" ... "{}"
), utilizzando il carattere NUL come separatore durante la lettura dei parametri (-0
).
Puoi provare
cp $(find . -iname "*FooBar*" | tail -2 ) dest
find . -iname "*FooBar*"|tail -n2|xargs -i cp "{}" dest
Sfortunatamente questo non funzionerà con nomi di file che contengono spazi o newline.