it-swarm-eu.dev

Příkaz Unix předepsat text do souboru

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
89
One Two Three
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ů.
78
printf '%s\n%s\n' "to be prepended" "$(cat text.txt)" >text.txt
135
shime

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
26
0xC0000022L

Substituce procesu

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


Zde String

Použijte zde řetězec - <<< (opět potřebujete bash), můžete:

<<< "to be prepended" < text.txt | sponge text.txt
22
Sridhar-Sarnobat

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
15
Adam

Preferovat { answer

Můžeme usnadnit použití houba . Nyní nepotřebujeme vytvořit dočasný soubor a přejmenovat ho 

echo -e "to be prepended \n another line" | cat - text.txt | sponge text.txt
11
ryan

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.

7
sehari24jam

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 ...

7
Rob I

Ř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

6
VasiliNovikov

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.
  • Všimněte si, jak jsou příkazy poskytnuty 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).
  • Následující řádky jsou text, který má vložit před aktuální řádek, zakončený . 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).
5
mklement0

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
3
Mert Nuhoglu

Dalším poměrně přímočarým řešením je:

    $ echo -e "string\n" $(cat file)
2
Pat

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.

1
AlexanderESmith

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
1
Ian Kelling
# 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
0
Jim

Žá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.

0
Evan Conrad

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.

0
AwesomeBobX64