Quando sto usando xargs
a volte non ho bisogno di utilizzare in modo esplicito la stringa sostituzione:Modifica sostituire stringa nella xargs
find . -name "*.txt" | xargs rm -rf
In altri casi, voglio specificare la stringa di sostituzione, al fine di fare le cose come:
find . -name "*.txt" | xargs -I '{}' mv '{}' /foo/'{}'.bar
il comando precedente dovrebbe spostare tutti i file di testo nella directory corrente in /foo
e aggiungerà l'estensione bar
a tutti i file.
Se invece di aggiungere del testo alla stringa di sostituzione, volevo modificare quella stringa in modo da poter inserire del testo tra il nome e l'estensione dei file, come potrei farlo? Ad esempio, supponiamo di voler fare lo stesso dell'esempio precedente, ma i file devono essere rinominati/spostati da <name>.txt
a /foo/<name>.bar.txt
(anziché /foo/<name>.txt.bar
).
UPDATE: riesco a trovare una soluzione:
find . -name "*.txt" | xargs -I{} \
sh -c 'base=$(basename $1) ; name=${base%.*} ; ext=${base##*.} ; \
mv "$1" "foo/${name}.bar.${ext}"' -- {}
ma mi chiedo se c'è un/soluzione migliore più breve.
No, tranne che avrei usato più citando "$ 1" "/ $ {nome} .bar foo' mv $ {ext}"' e si potrebbe fare '. basename' come questo: 'base = $ {1 ## * /}'. Dovresti pubblicare la tua soluzione come risposta e accettarla. –
@DennisWilliamson Grazie per il tuo commento! Aspetterò un po 'di più, solo per vedere se qualcuno si inventerà qualcosa di stravagante, altrimenti risponderò io stesso alla domanda. – betabandido
Penso che se il tuo nome file è l'ultima cosa sulla linea, non è necessario -I {} né {} nella riga di comando. (Si noti che il vero scopo di xargs è raggruppare però, quindi se NON volete più cose alla fine della chiamata di 1 xargs avete bisogno di "-l 1" (o -L 1 per alcune versioni di xargs). -I {} implica -l 1, ecco perché funziona anche qui.) –