sed in-place flaga, która działa zarówno na Mac (BSD) i Linux
Czy istnieje wywołanie sed
todo in-place editing without backups, które działa zarówno na Linuksie, jak i Macu? Podczas gdy BSD sed
dostarczane wraz z OS X wydaje się potrzebować sed -i '' …
, dystrybucje GNU sed
Linux zazwyczaj są dostarczane z interpretacją cudzysłowów jako pustej nazwy pliku wejściowego (zamiast rozszerzenia kopii zapasowej), a zamiast tego potrzebuje sed -i …
.
Czy jest jakaś składnia wiersza poleceń, która działa z obydwoma smakami, więc mogę używać tego samego skryptu na obu systemach?
14 answers
Jeśli naprawdę chcesz używać sed -i
w "łatwy" sposób, poniższe instrukcje działają zarówno na GNU, jak i BSD / Mac sed
:
sed -i.bak 's/foo/bar/' filename
Zwróć uwagę na brak miejsca i kropki.
Dowód:
# GNU sed
% sed --version | head -1
GNU sed version 4.2.1
% echo 'foo' > file
% sed -i.bak 's/foo/bar/' ./file
% ls
file file.bak
% cat ./file
bar
# BSD sed
% sed --version 2>&1 | head -1
sed: illegal option -- -
% echo 'foo' > file
% sed -i.bak 's/foo/bar/' ./file
% ls
file file.bak
% cat ./file
bar
Oczywiście można wtedy po prostu usunąć .bak
pliki.
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2019-09-19 20:28:35
To działa z GNU sed, ale nie na OS X:
sed -i -e 's/foo/bar/' target.file
sed -i'' -e 's/foo/bar/' target.file
To działa na OS X, ale nie z GNU sed:
sed -i '' -e 's/foo/bar/' target.file
Na OS X you
- nie można użyć
sed -i -e
, ponieważ rozszerzenie pliku kopii zapasowej będzie ustawione na-e
- nie może używać
sed -i'' -e
z tych samych powodów-potrzebuje spacji między-i
a''
.
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2019-09-19 20:28:25
Kiedy na OSX, zawsze instaluję wersję GNU sed poprzez Homebrew, aby uniknąć problemów w skryptach, ponieważ większość skryptów została napisana dla wersji GNU sed.
brew install gnu-sed --with-default-names
Wtedy twój BSD sed zostanie zastąpiony przez GNU sed.
Alternatywnie, można zainstalować bez domyślnych nazw, ale wtedy:
- zmień swoje
PATH
zgodnie z instrukcją po zainstalowaniugnu-sed
- sprawdź w swoich skryptach, aby wybrać pomiędzy
gsed
lubsed
w zależności od systemu
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2019-09-19 20:27:50
Jak Noufal Ibrahim pyta, dlaczego nie możesz używać Perla? Każdy Mac będzie miał Perla i jest bardzo niewiele dystrybucji Linuksa lub BSD, które nie zawierają jakiejś wersji Perla w systemie bazowym. Jednym z niewielu środowisk, w którym może brakować Perla, jest BusyBox (który działa jak GNU / Linux dla -i
, z tą różnicą, że nie można podać rozszerzenia kopii zapasowej).
As Ismail zaleca,
Ponieważ perl jest dostępny wszędzie, ja po prostu
perl -pi -e s,foo,bar,g target.file
I wydaje się to lepszym rozwiązaniem prawie w każdym przypadku niż skrypty, aliasy lub inne obejścia, aby poradzić sobie z podstawową niekompatybilnością sed -i
pomiędzy GNU/Linuksem a BSD/Mac.
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-05-23 12:26:43
Nie ma sposobu, aby to działało.
Jednym ze sposobów jest użycie pliku tymczasowego, takiego jak:
TMP_FILE=`mktemp /tmp/config.XXXXXXXXXX`
sed -e "s/abc/def/" some/file > $TMP_FILE
mv $TMP_FILE some/file
To działa na obu
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2019-09-19 20:27:44
ODPOWIEDŹ: Nie.
Pierwotnie przyjęta odpowiedź faktycznie nie robi tego ,co jest wymagane (jak zaznaczono w komentarzach). (Znalazłem tę odpowiedź szukając powodu, dla którego A file-e
pojawia się" losowo " w moich katalogach.)
Najwyraźniej nie ma sposobu, aby sed -i
działać konsekwentnie zarówno na MacOS, jak i Linuce.
Moim zaleceniem, o ile jest to warte, nie jest aktualizacja-in-place z sed
(która ma złożone tryby awarii), ale generowanie nowych pliki i zmienić ich nazwy później. Innymi słowy: unikać -i
.
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2012-07-04 09:38:45
Opcja -i
nie jest częścią POSIX Sed . Bardziej przenośną metodą byłoby
aby użyć Vima w trybie Ex:
ex -sc '%s/alfa/bravo/|x' file
-
%
Wybierz wszystkie linie -
s
zastąp -
x
Zapisz i zamknij
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2016-11-24 13:50:34
Oto kolejna wersja, która działa na Linuksie i macOS bez używania eval
i bez konieczności usuwania plików kopii zapasowych. Używa tablic Bash do przechowywania parametrów sed
, co jest czystsze niż użycie eval
:
# Default case for Linux sed, just use "-i"
sedi=(-i)
case "$(uname)" in
# For macOS, use two parameters
Darwin*) sedi=(-i "")
esac
# Expand the parameters in the actual call to "sed"
sed "${sedi[@]}" -e 's/foo/bar/' target.file
To nie tworzy pliku kopii zapasowej, ani pliku z dołączonymi cudzysłowami.
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2019-09-19 20:27:36
Odpowiedź Steve 'a Powella jest całkiem poprawna, zapoznanie się ze stroną MAN dla sed na OSX i Linuksie (Ubuntu 12.04) podkreśla kompatybilność w "in-place" sed wykorzystania w obu systemach operacyjnych.
JFYI, nie powinno być spacji między-i A cudzysłowami (które oznaczają puste rozszerzenie pliku) przy użyciu Linuksowej wersji sed, zatem
#Linux
sed -i""
I
#OSX (notice the space after the '-i' argument)
sed -i ""
I got round to w skrypcie za pomocą polecenia alias 'D i wyjścia nazwy systemu operacyjnego' uname 'w bash'if'. Próba przechowywania zależnych od systemu operacyjnego ciągów poleceń w zmiennych została zauważona i pominięta podczas interpretacji cudzysłowów. Użycie' shopt-s expand_aliases ' jest konieczne do rozszerzenia/użycia aliasów zdefiniowanych w skrypcie. korzystanie z shopt jest przedmiotem tutaj .
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-05-23 11:33:26
Natknąłem się na ten problem. Jedynym szybkim rozwiązaniem było zastąpienie sed w mac na wersję gnu:
brew install gnu-sed
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-07-20 21:47:58
Jeśli musisz wykonać sed
in-place w skrypcie bash
, a nie chcesz, aby wynik w in-place z .plików bkp, a Ty masz sposób na wykrycie systemu operacyjnego (powiedzmy, używając ostype.sh ), -- wtedy powinien zadziałać następujący hack z bash
powłoką wbudowaną eval
:
OSTYPE="$(bash ostype.sh)"
cat > myfile.txt <<"EOF"
1111
2222
EOF
if [ "$OSTYPE" == "osx" ]; then
ISED='-i ""'
else # $OSTYPE == linux64
ISED='-i""'
fi
eval sed $ISED 's/2222/bbbb/g' myfile.txt
ls
# GNU and OSX: still only myfile.txt there
cat myfile.txt
# GNU and OSX: both print:
# 1111
# bbbb
# NOTE:
# if you just use `sed $ISED 's/2222/bbbb/g' myfile.txt` without `eval`,
# then you will get a backup file with quotations in the file name,
# - that is, `myfile.txt""`
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-10-02 11:22:32
Możesz użyć gąbki. Sponge jest starym programem uniksowym, znalezionym w pakiecie moreutils (zarówno w ubuntu i prawdopodobnie Debianie, jak i w homebrew na Macu).
Spowoduje buforowanie całej zawartości z potoku, odczekanie aż potok się zamknie (prawdopodobnie oznacza to, że plik wejściowy jest już zamknięty), a następnie nadpisanie:
Synopsis
Sed"..."plik / grep"...'/Sponge file
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2013-08-06 13:16:50
Przenośny skrypt dla systemów GNU i OSX:
if [[ $(uname) == "Darwin" ]]; then
SP=" " # Needed for portability with sed
fi
sed -i${SP}'' -e "s/foo/bar/g" -e "s/ping/pong/g" foobar.txt
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2021-01-09 19:43:10
Na Linuksie i OS X działa Mi:
sed -i' ' <expr> <file>
Np. dla pliku f
zawierającego aaabbaaba
sed -i' ' 's/b/c/g' f
Daje aaaccaaca
zarówno na Linuksie, jak i Macu. Notatka zawiera cytowany łańcuch zawierający spację , z brak spacji pomiędzy -i
a łańcuchem. Pojedyncze lub podwójne cytaty działają.
Na Linuksie używam bash
wersji 4.3.11 pod Ubuntu 14.04.4 i na Mac wersji 3.2.57 pod OS X 10.11.4 El Capitan (Darwin 15.4.0).
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2016-04-19 15:24:08