Można użyć sed
„s w
flagę albo z /dev/stderr
, /dev/tty
, /dev/fd/2
jeśli jest obsługiwane w systemie. Np. Z wejściem file
takim jak:
foo first
second: missing
third: foo
none here
bieganie
sed -i '/foo/{
s//bar/g
w /dev/stdout
}' file
wyjścia:
bar first
third: bar
chociaż file
treść została zmieniona na:
bar first
second: missing
third: bar
none here
W twoim przypadku uruchamianie:
find . -type f -printf '\n%p:\n' -exec sed -i '/foo/{
s//bar/g
w /dev/fd/2
}' {} \;
edytuje pliki w miejscu i wyświetla:
./file1:
rzeczy w barze
więcej paska
./file2:
./file3:
pierwszy pasek
po trzecie: bar
Możesz również wydrukować coś takiego jak original line >>> modified line
np .:
find . -type f -printf '\n%p:\n' -exec sed -i '/foo/{
h
s//bar/g
H
x
s/\n/ >>> /
w /dev/fd/2
x
}' {} \;
edytuje pliki w miejscu i wyświetla:
./file1:
foo rzeczy >>> rzeczy bar
więcej foo >>> więcej paska
./file2:
./file3:
foo najpierw >>> najpierw pasek
trzeci: foo >>> trzeci: bar
for x in `find . -type f`; do echo ///File $x: ; sed --quiet 's/abc/def/gp' $x; done
sed
wyrażeń, nie chcę pisać/gp
dla każdego z nich. Jak ustawić globalnie?Nie sądzę, żeby to było możliwe, ale obejściem tego problemu może być użycie perla:
Spowoduje to wydrukowanie zmienionych linii na błąd standardowy. Na przykład:
Możesz również uczynić to nieco bardziej złożonym, drukując numer linii, nazwę pliku, oryginalną linię i zmienioną linię:
źródło
$ARGV
dla nazwy obsługiwanego pliku.perl
składnia jest bardzo podobna do tejsed
i nie sądzę, że to, o co prosisz, jest w rzeczywistości możliwesed
.Jest to możliwe przy użyciu wagowo flagę, która zapisuje aktualny wzór do pliku. Tak więc, dodając go do polecenia substitute, możemy raportować kolejne podstawienia do pliku i drukować go po zakończeniu zadania. Lubię też pokolorować zastąpiony ciąg grep.
Zauważ, że musi być tylko jedna spacja między w a nazwą pliku.
Jest to nawet lepsze niż diff, ponieważ diffing może również pokazywać zmiany, nawet jeśli nie zostały wykonane przez sed.
źródło
sed.done
. W związku z tym wiersze z „Do” w oryginalnym pliku nie są drukowanesed.done
, więc gdy zobaczyszgrep "To" sed.done
tylko linie, które zostały zmienionesed
. Nie zobaczysz oryginalnej linii w pliku, zanim nie zostanie ona zastąpiona, jeśli to jest to, do czegoLubię rozwiązanie @terdon - perl jest do tego dobry.
Oto moja ulepszona wersja, która:
kod
przykładowe wyjście
źródło