Cześć Chcę dodać tekst do pliku. Na przykład chcę dodać zadania na początku pliku todo.txt. Wiem o echo 'task goes here' >> todo.txttym, ale to dodaje wiersz na końcu pliku (nie to, czego chcę).
pierwszy działa świetnie! czy mógłbyś wyjaśnić logikę? nie jestem szczególnie pewien, jak interpretować składnię.
user479534
44
@ user8347: Pipe ( |) wiadomość ( echo '...'), do catktórej używa -(standardowe wejście) jako pierwszy plik i todo.txtjako drugi. catconCATenates wielu plików. Wyślij wyjście ( >) do pliku o nazwie temp. Jeśli nie ma błędów ( &&) z catpotem rename ( mv) z temppliku z powrotem do oryginalnego pliku ( todo.txt).
Dennis Williamson,
1
@itaifrenkel: Musiałbym zobaczyć, co zrobiłeś, ale jeśli catotrzyma dosłowny ukośnik odwrotny n, nie przekształci go w nowy wiersz. Coś jeszcze musiało to zrobić. Zamiast tego catspróbuj potokować, hexdump -Caby sprawdzić, czy faktycznie wysyłasz odwrotny ukośnik i n, czy jest to nowy wiersz. Możesz także spróbować cat -ewyświetlić zakończenia linii.
Dennis Williamson
1
Używanie 2 i 3 (3 wydaje mi się prostsze) pozwala na dodawanie tekstu do wielu plików jednocześnie.
Felix
4
@Kira: 1Środki wykonują następne polecenie tylko w pierwszej linii pliku, a ipolecenie jest wstawiane. Zajrzyj na stronę manuala w sekcji „Adresy” oraz w sekcji „Polecenia zerowe lub z jednym adresem”.
Działa to, ponieważ polecenie wewnątrz $(...)jest wykonywane przed todo.txtnadpisaniem> todo.txt
Podczas gdy inne odpowiedzi działają dobrze, o wiele łatwiej mi to zapamiętać, ponieważ codziennie używam echa i kota.
EDYCJA: To rozwiązanie jest bardzo złym pomysłem, jeśli występują jakieś ukośniki odwrotne todo.txt, ponieważ dzięki -eflagom echo je zinterpretuje. Innym, o wiele łatwiejszym sposobem umieszczenia nowego wiersza w ciągu przedmowy jest ...
echo "task goes here
$(cat todo.txt)"> todo.txt
... po prostu używać nowych linii. Jasne, nie jest to już jedna linijka, ale realistycznie też nie była wcześniej liniowa. Jeśli robisz to w skrypcie i martwisz się wcięciem (np. Wykonujesz to wewnątrz funkcji), istnieje kilka sposobów obejścia tego problemu, w tym:
„Absorbuje” STDIN, a następnie zapisuje do pliku, co oznacza, że nie musisz się martwić o pliki tymczasowe i ich przenoszenie.
Możesz uzyskać moreutilsz wieloma dystrybucjami Linuksa, przez apt-get install moreutilslub w systemie OS X za pomocą Homebrew , z brew install moreutils.
Powiedz, że brakuje Ci miejsca na dysku, więc new_todo.txtzapisuje się tylko częściowo. Wygląda na to, że Twoje rozwiązanie traci oryginalny plik.
NPE
Kto zabraknie miejsca na dysku? ;-) To tylko prosty przykład.
Keith
2
@Keith Ktoś pracujący na maszynie wirtualnej, który nie spodziewał się, że będzie potrzebował szczególnie dużego dysku wirtualnego. Lub ktoś przenosi duży plik. W każdym razie prawdziwym argumentem przeciwko temu są uprawnienia do katalogu; jeśli nie masz uprawnień do tworzenia nowych plików w danym katalogu, jedyną komendą, którą z powodzeniem wykonasz w skrypcie, jest rmoryginalny plik.
Parthian Shot
3
Jeśli plik tekstowy jest wystarczająco mały, aby zmieścić się w pamięci, nie trzeba tworzyć pliku tymczasowego, aby go zastąpić. Możesz załadować to wszystko do pamięci i zapisać z powrotem do pliku.
Wystarczy zadać oczywiste pytanie: gdzie jest limit znaków zmiennych powłoki?
nixda
O ile mi wiadomo, jest to ograniczone tylko ilością dostępnej pamięci. Wypełniłem do pamięci zmienne znacznie przekraczające 100 MB. text=$(cat file). Uważaj jednak, aby używać tylko tekstu, ponieważ zmienne powłoki nie są binarnie czyste mywiki.wooledge.org/BashFAQ/058
Rucent88
2
Nie można wstawiać treści na początku pliku. Jedyne, co możesz zrobić, to albo zastąpić istniejącą zawartość, albo dołączyć bajty po bieżącym końcu pliku.
Każde rozwiązanie twojego pytania wymaga utworzenia pliku tymczasowego (lub bufora) (w pamięci lub na dysku), który ostatecznie zastąpi oryginalny plik.
Uważaj, aby nie utracić danych, zachowując oryginalny plik podczas tworzenia nowego, jeśli w tym czasie system plików będzie pełny. na przykład:
Downvoters mogą wyjaśnić swoją motywację. Żadna z pozostałych odpowiedzi, w tym odpowiedź zaakceptowana, nie stoi w sprzeczności z moją odpowiedzią.
jlliagre 12.04.16
Trudno to parsować, ponieważ <...> wyglądają jak nawiasy, które, jak zakładam, nie są.
Odstęp
To mi nie działa. echo HOME=\"/g/Users/timregan/\" | cat - 'F:\Program Files\Git\etc\profile'działa, ale cat <echo HOME=\"/g/Users/timregan/\" 'F:\Program Files\Git\etc\profile'wyświetla błąd „echo: brak takiego pliku lub katalogu”
dumbledad
@dumbledad Zastanawiasz się nad moją odpowiedzią. Nie ma w tym nic do przeanalizowania. Odstęp między <i (złamałby składnię. Spróbujcat <(echo HOME=\"/g/Users/timregan/\") 'F:\Program Files\Git\etc\profile'
jlliagre
1
Możesz użyć tee:
echo 'task goes here'| cat - todo.txt | tee todo.txt
Odpowiedzi:
lub
lub
źródło
|
) wiadomość (echo '...'
), docat
której używa-
(standardowe wejście) jako pierwszy plik itodo.txt
jako drugi.cat
conCATenates wielu plików. Wyślij wyjście (>
) do pliku o nazwietemp
. Jeśli nie ma błędów (&&
) zcat
potem rename (mv
) ztemp
pliku z powrotem do oryginalnego pliku (todo.txt
).cat
otrzyma dosłowny ukośnik odwrotny n, nie przekształci go w nowy wiersz. Coś jeszcze musiało to zrobić. Zamiast tegocat
spróbuj potokować,hexdump -C
aby sprawdzić, czy faktycznie wysyłasz odwrotny ukośnik i n, czy jest to nowy wiersz. Możesz także spróbowaćcat -e
wyświetlić zakończenia linii.1
Środki wykonują następne polecenie tylko w pierwszej linii pliku, ai
polecenie jest wstawiane. Zajrzyj na stronę manuala w sekcji „Adresy” oraz w sekcji „Polecenia zerowe lub z jednym adresem”.Moim zdaniem prostszą opcją jest:
Działa to, ponieważ polecenie wewnątrz
$(...)
jest wykonywane przedtodo.txt
nadpisaniem> todo.txt
Podczas gdy inne odpowiedzi działają dobrze, o wiele łatwiej mi to zapamiętać, ponieważ codziennie używam echa i kota.
EDYCJA: To rozwiązanie jest bardzo złym pomysłem, jeśli występują jakieś ukośniki odwrotne
todo.txt
, ponieważ dzięki-e
flagom echo je zinterpretuje. Innym, o wiele łatwiejszym sposobem umieszczenia nowego wiersza w ciągu przedmowy jest ...... po prostu używać nowych linii. Jasne, nie jest to już jedna linijka, ale realistycznie też nie była wcześniej liniowa. Jeśli robisz to w skrypcie i martwisz się wcięciem (np. Wykonujesz to wewnątrz funkcji), istnieje kilka sposobów obejścia tego problemu, w tym:
Ponadto, jeśli zależy Ci na dodaniu nowej linii na końcu
todo.txt
, nie używaj ich. Cóż, z wyjątkiem przedostatniego. To nie zadziera z końcem.źródło
-e
konwertowane sekwencje specjalne również nie będą konwertowane w todo.txt?moreutils
Mieć ładny narzędzie o nazwiesponge
:„Absorbuje” STDIN, a następnie zapisuje do pliku, co oznacza, że nie musisz się martwić o pliki tymczasowe i ich przenoszenie.
Możesz uzyskać
moreutils
z wieloma dystrybucjami Linuksa, przezapt-get install moreutils
lub w systemie OS X za pomocą Homebrew , zbrew install moreutils
.źródło
(echo 'ble'; cat todo.txt)
:-)Możesz używać Vima w trybie Ex:
1
wybierz pierwszą linięi
wstawićx
Zapisz i zamknijźródło
Możesz utworzyć nowy plik tymczasowy.
Możesz także użyć
sed
lubawk
. Ale w zasadzie dzieje się to samo.źródło
new_todo.txt
zapisuje się tylko częściowo. Wygląda na to, że Twoje rozwiązanie traci oryginalny plik.rm
oryginalny plik.Jeśli plik tekstowy jest wystarczająco mały, aby zmieścić się w pamięci, nie trzeba tworzyć pliku tymczasowego, aby go zastąpić. Możesz załadować to wszystko do pamięci i zapisać z powrotem do pliku.
Nie można dodawać wierszy na początku pliku bez zapisywania całego pliku.
źródło
text=$(cat file)
. Uważaj jednak, aby używać tylko tekstu, ponieważ zmienne powłoki nie są binarnie czyste mywiki.wooledge.org/BashFAQ/058Nie można wstawiać treści na początku pliku. Jedyne, co możesz zrobić, to albo zastąpić istniejącą zawartość, albo dołączyć bajty po bieżącym końcu pliku.
Każde rozwiązanie twojego pytania wymaga utworzenia pliku tymczasowego (lub bufora) (w pamięci lub na dysku), który ostatecznie zastąpi oryginalny plik.
Uważaj, aby nie utracić danych, zachowując oryginalny plik podczas tworzenia nowego, jeśli w tym czasie system plików będzie pełny. na przykład:
źródło
echo HOME=\"/g/Users/timregan/\" | cat - 'F:\Program Files\Git\etc\profile'
działa, alecat <echo HOME=\"/g/Users/timregan/\" 'F:\Program Files\Git\etc\profile'
wyświetla błąd „echo: brak takiego pliku lub katalogu”<
i(
złamałby składnię. Spróbujcat <(echo HOME=\"/g/Users/timregan/\") 'F:\Program Files\Git\etc\profile'
Możesz użyć
tee
:źródło
GitBash + Windows10 + Multline :
Oto wersja, która pozwala używać ciągów wieloliniowych .
źródło