GNU/Linux >> Znalost Linux >  >> Linux

Jak dosáhnout přenositelnosti pomocí Sed -i (úpravy na místě)?

Píšu skripty shellu pro svůj server, což je sdílený hosting, na kterém běží FreeBSD. Také je chci mít možnost testovat lokálně na svém PC s Linuxem. Proto se je snažím psát přenosným způsobem, ale pomocí sed Nevidím způsob, jak to udělat.

Část mého webu používá generované statické HTML soubory a tento řádek sed vkládá správný DOCTYPE po každé regeneraci:

sed -i '1s/^/<!DOCTYPE html> n/' ${file_name.html}

Funguje s GNU sed na Linuxu, ale FreeBSD sed očekává první argument po -i možnost být rozšířením pro záložní kopii. Takto by to vypadalo:

sed -i '' '1s/^/<!DOCTYPE html> n/' ${file_name.html}

Nicméně GNU sed dále očekává, že výraz bude následovat bezprostředně za -i .
(Vyžaduje také opravy se zpracováním nového řádku, ale to již bylo zodpovězeno zde)

Samozřejmě mohu tuto změnu zahrnout do své serverové kopie skriptu, ale to by zkazilo moje použití VCS pro verzování. Existuje způsob, jak toho dosáhnout pomocí sed plně přenosným způsobem?

Přijatá odpověď:

GNU sed přijímá volitelné rozšíření za -i . Rozšíření musí být ve stejném argumentu bez mezery. Tato syntaxe funguje také na BSD sed.

sed -i.bak -e '…' SOMEFILE

Všimněte si, že na BSD -i také mění chování, když existuje více vstupních souborů:jsou zpracovávány nezávisle (takže např. $ odpovídá poslednímu řádku každého souboru). Toto také nebude fungovat na BusyBox.

Pokud nechcete používat záložní soubory, můžete zkontrolovat, která verze sed je k dispozici.

case $(sed --help 2>&1) in
  *GNU*) set sed -i;;
  *) set sed -i '';;
esac
"[email protected]" -e '…' "$file"

Nebo alternativně, abyste se vyhnuli ucpání pozičních parametrů, definujte funkci.

case $(sed --help 2>&1) in
  *GNU*) sed_i () { sed -i "[email protected]"; };;
  *) sed_i () { sed -i '' "[email protected]"; };;
esac
sed_i -e '…' "$file"

Pokud se nechcete obtěžovat, použijte Perl.

perl -i -pe '…' "$file"

Pokud chcete napsat přenosný skript, nepoužívejte -i – není v POSIX. Dělejte ručně to, co sed dělá pod pokličkou – je to jen jeden další řádek kódu.

sed -e '…' "$file" >"$file.new"
mv -- "$file.new" "$file"

Linux
  1. Jak nahradit text podobný sedu pythonem?

  2. Jak nahradím jednoduché uvozovky jiným znakem v sed?

  3. Jak podložit soubor pomocí FF pomocí dd?

  1. Jak nahradit řetězec řetězcem obsahujícím lomítko se Sed?

  2. Jak rekurzivně nahradit znaky sed?

  3. Jak změnit soubor na místě pomocí awk? (jako u sed -i)

  1. Jak použít Sed nebo Ex k nahrazení bloku (víceřádkového kódu) novým blokem textu (kódu)?

  2. Jak mohu pomocí sed změnit své konfigurační soubory s flexibilními klíči a hodnotami?

  3. Jak třídit soubor na místě