Existuje příkaz Unixu, který předpíše některá data řetězce do textového souboru?
Něco jako:
prepend "to be prepended" text.txt
sed -i.old '1s;^;to be prepended;' inFile
-i
zapíše změnu na místo a provede zálohu v případě, že je poskytnuta nějaká přípona. (V tomto případě .old
)1s;^;to be prepended;
nahrazuje začátek prvního řádku daným řetězcem nahrazení pomocí ;
jako oddělovače příkazů.printf '%s\n%s\n' "to be prepended" "$(cat text.txt)" >text.txt
To je jedna z možností:
(echo "to be prepended"; cat text.txt) > newfile.txt
pravděpodobně nebudete snadno obejít mezilehlý soubor.
Alternativy (mohou být těžkopádné s únikem Shell):
sed -i '0,/^/s//to be prepended/' text.txt
To mě překvapilo.
cat <(echo "before") text.txt > newfile.txt
což je pravděpodobně přirozenější než přijatá odpověď (tisk něčeho a jeho vložení do substitučního příkazu je lexikograficky proti-intuitivní).
... a únos toho, co říkal výše, s sponge
nepotřebujete dočasný soubor:
Sudo apt-get install moreutils
<<(echo "to be prepended") < text.txt | sponge text.txt
EDIT: Zdá se, že to nefunguje v Bourne Shell /bin/sh
Použijte zde řetězec - <<<
(opět potřebujete bash), můžete:
<<< "to be prepended" < text.txt | sponge text.txt
To bude fungovat pro vytvoření výstupu. - znamená standardní vstup, který je poskytován přes trubku od echo.
echo -e "to be prepended \n another line" | cat - text.txt
Pro přepsání souboru je vyžadován dočasný soubor, protože se nemůže vrátit zpět do vstupního souboru.
echo "to be prepended" | cat - text.txt > text.txt.tmp
mv text.txt.tmp text.txt
V některých případech může být předpřipravený text k dispozici pouze ze stdin. Pak tato kombinace funguje.
echo "to be prepended" | cat - text.txt | tee text.txt
Pokud chcete vynechat tee
výstup, pak přidejte > /dev/null
.
Pravděpodobně nic vestavěného, ale můžete si to jednoduše napsat, jako je tento:
#!/bin/bash
echo -n "$1" > /tmp/tmpfile.$$
cat "$2" >> /tmp/tmpfile.$$
mv /tmp/tmpfile.$$ "$2"
Něco takového ...
Řešení:
printf '%s\n%s' 'text to prepend' "$(cat file.txt)" > file.txt
Všimněte si, že je to bezpečné pro všechny druhy vstupů, protože neexistují žádné rozšíření. Chcete-li například předplatit [email protected]#$%^&*()ugly text\n\t\n
, bude fungovat pouze:
printf '%s\n%s' '[email protected]#$%^&*()ugly text\n\t\n' "$(cat file.txt)" > file.txt
Poslední část, kterou je třeba zvážit, je odstranění mezer na konci souboru během substituce příkazu "$(cat file.txt)"
. Všechny práce jsou poměrně složité. Pokud chcete zachovat nové řádky na konci souboru.txt, přečtěte si toto: https://stackoverflow.com/a/22607352/1091436
Pokud je to přijatelné pro nahradit vstupní soubor:
Poznámka: Dělá tak, že {může mít neočekávané vedlejší účinky, zejména nahrazení symbolického odkazu běžným souborem, případně s různými oprávněními k souboru a změnou data vytvoření (narození) souboru .
sed -i
, jako v odpověď prince Johna Wesleyho , se snaží alespoň obnovit původní oprávnění, ale ostatní omezení platí.
{ printf 'line 1\nline 2\n'; cat text.txt; } > tmp.txt && mv tmp.txt text.txt
Poznámka: Použití příkazu group{ ...; ... }
je efektivnější než použití znaku subshell ((...; ...)
).
Je-li vstupní soubor by měl být upraven na místě (zachování jeho inodu se všemi jeho atributy}:
Používání užitného ed
nástroje POSIX :
Poznámka: ed
vždy přečte vstupní soubor jako celek do paměti.
ed -s text.txt <<'EOF'
1i
line 1
line 2
.
w
EOF
-s
potlačeny stavové zprávy ed
.ed
jako multi-line zde-document (<<'EOF' ... EOF
), tj. Přes stdin.1i
vytvoří 1
(první řádek) aktuální řádek a spustí režim vkládání (i
)..
na vlastním řádku.w
zapíše výsledek zpět do vstupního souboru (pro testování nahraďte w
s ,p
pouze print výsledek, bez změny vstupního souboru).Jiný způsob použití sed
:
sed -i.old '1 {i to be prepended
}' inFile
Pokud je řádek, který má být předpřipraven, víceřádkový:
sed -i.old '1 {i\
to be prepended\
multiline
}' inFile
Dalším poměrně přímočarým řešením je:
$ echo -e "string\n" $(cat file)
Jako testováno v Bash (v Ubuntu), pokud začínáte testovacím souborem přes;
echo "Original Line" > test_file.txt
můžete provést;
echo "$(echo "New Line"; cat test_file.txt)" > test_file.txt
nebo pokud je verze bash pro $ () příliš stará, můžete použít backticks;
echo "`echo "New Line"; cat test_file.txt`" > test_file.txt
a obdržet následující obsah "test_file.txt";
New Line
Original Line
Žádný zprostředkující soubor, jen bash/echo.
Pokud se vám líbí vi/vim, může to být váš styl.
printf '0i\n%s\n.\nwq\n' prepend-text | ed file
# create a file with content..
echo foo > /tmp/foo
# prepend a line containing "jim" to the file
sed -i "1s/^/jim\n/" /tmp/foo
# verify the content of the file has the new line prepened to it
cat /tmp/foo
Žádná z odpovědí se mi moc nelíbila, takže jsem si vytvořil vlastní příkaz: pre
.
Instalovat s go:
go get -u github.com/Flaque/pre
Předat nějaký text ze stdin do souboru s:
echo "some at the start" | pre myFile.txt | sponge myFile.txt
Příkaz nepíše na místo, je to jen výstup na stdout, takže budete potřebovat sponge
z moreutils
na konci pro uložení souboru.
Doporučuji definovat funkci a pak ji importovat a používat tam, kde je to potřeba.
prepend_to_file() {
file=$1
text=$2
if ! [[ -f $file ]] then
touch $file
fi
echo "$text" | cat - $file > $file.new
mv -f $file.new $file
}
Použijte jej takto:
prepend_to_file test.txt "This is first"
prepend_to_file test.txt "This is second"
Obsah vašeho souboru pak bude:
This is second
This is first
Chystám se použít tento přístup pro implementaci updateru protokolu změn.