znajdź i sed (wyszukaj i zamień)

27

Używam następującego polecenia na moim komputerze Mac:

$find . -name “*.java” -exec sed -i ’s/foo/bar/g’ {} \;

i wydaje się, że nie ma żadnego efektu.

Mam dwa pliki w katalogu, które kończą się na .java, które zawierają tekst foo. Czy coś brakuje?

EDYCJA: Wyniki z prośby o komentarze

[aafghani-03:~/test amirafghani]$ find . -name "*.java" -exec sed -i 's/foo/bar/g' {} \;
sed: 1: "./bar.java": invalid command code .
sed: 1: "./foo.java": invalid command code .
Amir Afghani
źródło
2
Czy to dokładnie to, co biegasz? Co jeśli usuniesz -execi wszystko po nim? Czy drukuje nazwy plików Java? (Martwię się, że używasz inteligentnych cytatów zamiast cytatów ASCII.)
Mikel
1
Właściwie to to rozwiązuje, przynajmniej dla mnie. Zarówno podwójne, jak i pojedyncze cudzysłowy należy zastąpić odpowiednio przez "i '.
Lev Levitsky,
2
Inteligentne (?) Cytaty! .. :)
Peter.O,
To, co wkleiłem, było dokładnie tym, co biegłem. Czy ktoś może opublikować odpowiedź?
Amir Afghani,
1
Następnym razem opublikuj komunikat o błędzie wyświetlany podczas zadawania pytania. Zaoszczędzi to wszystkim czas.
Mikel

Odpowiedzi:

34

Przede wszystkim upewnij się, że używasz regularnych cytatów ascii, takich jak "i '(odpowiednio kody ascii 0x22i 0x27) w skryptach powłoki, ponieważ przykład w twoim poście zawiera niestandardowe znaki cytowania. Jeśli przyjrzysz się uważnie, wyglądają nieco inaczej. Najprawdopodobniej jest to błąd kopiowania i wklejania z formatu dokumentu tekstu sformatowanego, takiego jak Word, OOWriter, a nawet okno przeglądarki.

Ponieważ jesteś na komputerze Mac, najprawdopodobniej masz implementację FreeBSD sed, w którym to przypadku musisz napisać polecenie w ten sposób:

find . -name "*.java" -exec sed -i '' s/foo/bar/g {} +

(tutaj, +zamiast używać \;jednego sedwywołania na plik).

W realizacji FreeBSD z sedtej -iflagi potrzebuje argument: rozszerzenie pliku kopii zapasowej. Na przykład za -i .bakpomocą polecenia utworzono kopię zapasową file1.txtjako file1.txt.bakpierwszą przed wykonaniem zamiany w oryginalnym pliku. Użycie pustego argumentu ''oznacza nieużywanie pliku kopii zapasowej, który wydaje się być tym, czego chcesz.

To samo w implementacji GNU (lub NetBSD, OpenBSD, busybox) to:

find . -name "*.java" -exec sed -i s/foo/bar/g {} +

Dziękuję @bahamat i @Mikel i @ pieter-breed za ulepszenie mojej odpowiedzi w twoich komentarzach.

Przestań krzywdzić Monikę
źródło
Co robią nawiasy klamrowe?
Zane Hitchcox
3
@ZaneHitchcox nawiasy klamrowe są symbolami zastępczymi dla dopasowanej nazwy pliku
Przestań szkodzić Monice