Risposte:
OS X utilizza un mix di strumenti BSD e GNU, quindi è meglio controllare sempre la documentazione (anche se l'ho avuto che less
non era nemmeno conforme alla manpage di OS X):
sed prende l'argomento dopo -i
come estensione per i backup. Fornire una stringa vuota ( -i ''
) per nessun backup.
Quanto segue dovrebbe fare:
LC_ALL=C find . -type f -name '*.txt' -exec sed -i '' s/this/that/ {} +
Il -type f
è solo buone pratiche; sed si lamenterà se gli dai una directory o giù di lì.
-exec
è preferito sopra xargs
; non devi preoccuparti di -print0
niente o altro. Alla {} +
fine significa che find
aggiungerà tutti i risultati come argomenti a un'istanza del comando chiamato, invece di rieseguirlo per ogni risultato. (Un'eccezione è quando viene violato il numero massimo di argomenti della riga di comando consentiti dal sistema operativo; in tal caso find
verrà eseguita più di un'istanza.)
%
carattere: sed "s%localhost/site%blah/blah%"
. Un'altra alternativa è quella di barra inversa sfuggire il separatore: sed "s/localhost\/site/blah\/blah/"
.
illegal byte sequence
errore? in tal caso, prova:, LC_ALL=C find . -type f -name '*.txt' -exec sed -i '' s/this/that/ {} +
ha funzionato per me.
/g
per più occasioni comeLC_ALL=C find . -type f -exec sed -i '' s/search/replace/g {} +
Per il mac, un approccio più simile sarebbe questo:
find . -name '*.txt' -print0 | xargs -0 sed -i "" "s/form/forms/g"
find . -name '*.php' -print0 | xargs -0 sed -i "" "s/easyform/form360/g"
Come soluzione alternativa, sto usando questo su Mac OSX 10.7.5
grep -ilr 'old-word' * | xargs -I@ sed -i '' 's/old-word/new-word/g' @
Il merito va a: la risposta di Todd Cesere
Nessuna delle precedenti funzioni su OSX.
Eseguire le seguenti operazioni:
perl -pi -w -e 's/SEARCH_FOR/REPLACE_WITH/g;' *.txt
Una versione che funziona su Linux e Mac OS X (aggiungendo l' -e
opzione a sed
):
export LC_CTYPE=C LANG=C
find . -name '*.txt' -print0 | xargs -0 sed -i -e 's/this/that/g'
export LC_CTYPE=C && export LANG=C
Ogni volta che scrivo questo comando, mi sembra sempre di intasarlo o di dimenticare una bandiera. Ho creato un Gist su github sulla base della risposta di TaylanUB che sostituisce una ricerca globale dalla directory corrente. Questo è specifico per Mac OSX.
https://gist.github.com/nateflink/9056302
È bello perché ora apro un terminale e poi copio:
curl -s https://gist.github.com/nateflink/9056302/raw/findreplaceosx.sh | bash -s "find-a-url.com" "replace-a-url.com"
È possibile ottenere alcuni strani errori di sequenza di byte, quindi ecco il codice completo:
#!/bin/bash
#By Nate Flink
#Invoke on the terminal like this
#curl -s https://gist.github.com/nateflink/9056302/raw/findreplaceosx.sh | bash -s "find-a-url.com" "replace-a-url.com"
if [ -z "$1" ] || [ -z "$2" ]; then
echo "Usage: ./$0 [find string] [replace string]"
exit 1
fi
FIND=$1
REPLACE=$2
#needed for byte sequence error in ascii to utf conversion on OSX
export LC_CTYPE=C;
export LANG=C;
#sed -i "" is needed by the osx version of sed (instead of sed -i)
find . -type f -exec sed -i "" "s|${FIND}|${REPLACE}|g" {} +
exit 0
Ho usato questo formato - ma ... ho scoperto che dovevo eseguirlo tre o più volte per farlo cambiare davvero ogni istanza che trovavo estremamente strana. Eseguirlo una volta cambierebbe alcuni in ogni file ma non in tutti. Eseguire esattamente la stessa stringa due o quattro volte catturerebbe tutte le istanze.
find . -type f -name '*.txt' -exec sed -i '' s/thistext/newtext/ {} +
g
alla fine, altrimenti sostituisce solo la prima occorrenza di thistext
una riga. Quindi il tuo regex dovrebbe esseres/thistext/newtext/g
https://bitbucket.org/masonicboom/serp è un'utilità go (ovvero multipiattaforma), testata su OSX, che effettua ricorsivi ricerca e sostituzione di testo nei file all'interno di una determinata directory e conferma ogni sostituzione. È nuovo, quindi potrebbe essere difettoso.
L'utilizzo è simile a:
$ ls test
a d d2 z
$ cat test/z
hi
$ ./serp --root test --search hi --replace bye --pattern "*"
test/z: replace hi with bye? (y/[n]) y
$ cat test/z
bye
find . -type f | xargs sed -i '' 's/string1/string2/g'
Fare riferimento qui per maggiori informazioni.
Il comando su OSX dovrebbe essere esattamente lo stesso di Unix nella graziosa UI.
-print0
aggiungere alle find
bandiere e -0
alle xargs
bandiere.
-exec sed -i s/this/that/g {} \+
invece di -print
e xargs
xargs
potrebbe vedere lo spazio delimitato "./jacobus" come un file a cui passare sed
, quindi con "R.txt" , nessuno dei quali esiste.
potrei semplicemente dire $ PWD invece di "."
apple.stackexchange.com
perché non è abbastanza generico per Linux né per tutti gli sviluppatori.