Czy istnieje polecenie systemu Unix, które dołącza jakieś dane tekstowe do pliku tekstowego?
Coś jak:
prepend "to be prepended" text.txt
unix
command-line
utilities
prepend
Raz Dwa Trzy
źródło
źródło
<<(echo "to be prepended") < text.txt | sponge text.txt
Odpowiedzi:
-i
zapisuje zmianę w miejscu i tworzy kopię zapasową, jeśli podano jakiekolwiek rozszerzenie. (W tym przypadku.old
)1s;^;to be prepended;
zastępuje początek pierwszego wiersza podanym ciągiem zastępującym, używając;
jako separatora polecenia.źródło
\n
po poprzedzeniu; w zależności od ich potrzeb. Zgrabne rozwiązanie.inFile
zawierać katalogi w swojej ścieżce?\n
. Powinienem był najpierw przeczytać komentarze. Cholera.'1s;^;my-prepended-line\;\n;'
źródło
git config --get-regex $arg | sed -r 's/\t{3}/\\n/g';
i to się psuje, ponieważ konwertuje\t
i\n
.echo "to be prepended"$'\n'"$(cat text.txt)"
Zastępowanie procesu
Dziwię się, że nikt o tym nie wspomniał.
co jest prawdopodobnie bardziej naturalne niż przyjęta odpowiedź (wydrukowanie czegoś i przekierowanie do polecenia podstawienia jest leksykograficznie sprzeczne z intuicją).
... i przejmując to, co powiedział Ryan powyżej,
sponge
nie potrzebujesz tymczasowego pliku:EDYCJA: Wygląda na to, że to nie działa w Bourne Shell
/bin/sh
Here String (tylko zsh)
Używając tu-string -
<<<
, możesz:źródło
<<(echo "to be prepended") < text.txt
i<<< "to be prepended" < text.txt
konstrukcje nie działają w bash; wymagają zsh.To jest jedna możliwość:
prawdopodobnie nie będziesz łatwo obejść pliku pośredniego.
Alternatywy (mogą być uciążliwe przy ucieczce z powłoki):
źródło
cat <(echo "to be prepended") text.txt > newfile.txt
. Pomyśl o tym, nie jestem pewien, czy mój jest powiązany, więc zamieszczam osobną odpowiedź.To zadziała, aby utworzyć wynik. - oznacza standardowe wejście, które jest dostarczane przez potok z echa.
Aby przepisać plik, wymagany jest plik tymczasowy, ponieważ nie można przesłać z powrotem do pliku wejściowego.
źródło
text.txt
zgodnie z żądaniem, ale wyświetla go na standardowe wyjście. Dane wyjściowe mogą zostać przeniesione do innego pliku, jeśli to zadziała dla OPWolę odpowiedź Adama
Możemy ułatwić korzystanie z gąbki . Teraz nie musimy tworzyć pliku tymczasowego i zmieniać jego nazwy o
źródło
Jeśli zastąpienie pliku wejściowego jest dopuszczalne :
Uwaga:
Może to mieć nieoczekiwane skutki uboczne, w szczególności potencjalnie zastąpienie linku symbolicznego zwykłym plikiem, w wyniku czego otrzymamy inne uprawnienia do pliku i zmianę daty utworzenia (urodzenia) pliku.
sed -i
, jak w odpowiedzi księcia Johna Wesleya , próbuje przynajmniej przywrócić pierwotne uprawnienia, ale inne ograniczenia mają również zastosowanie.Oto prosta alternatywa, która używa pliku tymczasowego (pozwala uniknąć wczytywania całego pliku wejściowego do pamięci, tak jak robi to rozwiązanie shime ):
Użycie polecenia grupy (
{ ...; ...; }
) jest nieco bardziej wydajne niż użycie podpowłoki ((...; ...)
), jak w rozwiązaniu 0xC0000022L .Zalety to:
Łatwo jest kontrolować, czy nowy tekst ma być dodawany bezpośrednio do pierwszego wiersza, czy też powinien być wstawiany jako nowy wiersz (po prostu dołącz
\n
doprintf
argumentu).W przeciwieństwie do
sed
rozwiązania działa, jeśli plik wejściowy jest pusty (0
bajty).sed
Rozwiązanie może być uproszczona, jeżeli zamiarem jest dołączana jeden lub więcej całych linii z istniejącym zawartości (przy założeniu, że plik źródłowy jest niepusty)sed
„Si
wkładki funkcyjne całych liniach:Z GNU
sed
:Wersja przenośna, która działa również z macOS / BSD
sed
:Zwróć uwagę, że
\
wymagany jest dosłowny znak nowej linii po znaku .Jeśli plik wejściowy musi być edytowany na miejscu (zachowując jego i-węzeł ze wszystkimi atrybutami):
Używając czcigodnego
ed
narzędzia POSIX :Uwaga:
ed
nieodmiennie najpierw wczytuje plik wejściowy jako całość do pamięci.Aby dołączyć bezpośrednio do pierwszej linii (tak jak w przypadku
sed
, nie zadziała, jeśli plik wejściowy jest całkowicie pusty (0
bajty)):-s
wyłączoneed
komunikaty o stanie.ed
w postaci wielowierszowego dokumentu here (<<EOF\n...\nEOF
), tj. Przez stdin ; domyślnie interpretacja łańcuchów jest wykonywana w takich dokumentach (zmienne powłoki są interpolowane); zacytować ogranicznik otwierający, aby to pominąć (np<<'EOF'
.).1
ustawia pierwszą linię jako bieżącąs
wykonuje oparte na wyrażeniach regularne podstawianie napisów w bieżącej linii, jak wsed
; możesz dołączyć dosłowne znaki nowej linii w zastępowanym tekście, ale muszą być one\
poprzedzone znakiem -escap.w
pisze plecy wynik do pliku wejściowego (do testowania, należy wymienićw
z,p
tylko wydrukować wynik, bez modyfikowania pliku wejściowego).Aby dodać jeden lub więcej całych wierszy :
Podobnie jak w przypadku
sed
,i
funkcja niezmiennie dodaje końcowy znak nowej linii do wstawianego tekstu.0 i
ustawia0
(początek pliku) w bieżącej linii i uruchamia tryb wstawiania (i
); zwróć uwagę, że numery linii są1
oparte na innych zasadach..
w osobnym wierszu.źródło
Prawdopodobnie nic wbudowanego, ale możesz łatwo napisać własne, na przykład:
Coś takiego przynajmniej ...
źródło
$$
Jednak użycie jest niewystarczające dla kodu produkcyjnego (atak na link symboliczny google); ale z pewnością jest lepsze niż statyczna nazwa pliku.mktemp
W pewnych okolicznościach tekst poprzedzony może być dostępny tylko ze standardowego wejścia. Wtedy ta kombinacja zadziała.
Jeśli chcesz pominąć
tee
dane wyjściowe, dołącz> /dev/null
.źródło
tee
która nie odbije się,text.txt
zanimcat
ją przeczytasz? Myślę, że nie - co uczyniłoby to rozwiązanie niebezpiecznym dla zdrowia pliku.lenA=1000000; yes a | head -c $lenA > a.txt; lenB=10000; b=$(yes b | head -c $lenB); echo "$b" | cat - a.txt | tee a.txt > /dev/null
. JeślilenA
ma wartość 1000000 (plik 1lenB
MB ) i 10000 (10 KB z dołączonym tekstem), to plik „a.txt” jest zastępowany 20 KB liter „b”. To jest całkowicie zepsute. Teraz, jeśli używasz 1Mb a.txt i 1Mb tekstu do dodania na początku,tee
przechodzi do pętli generującej plik 7Gb +, musiałem zatrzymać polecenie. Jest więc oczywiste, że wynik jest nieprzewidywalny w przypadku dużych rozmiarów. Nie mam informacji, czy powinien działać na małych rozmiarach.Rozwiązanie:
Zauważ, że jest to bezpieczne dla wszystkich rodzajów wejść, ponieważ nie ma rozszerzeń. Na przykład, jeśli chcesz wstawić na początku
!@#$%^&*()ugly text\n\t\n
, zadziała:Ostatnią częścią do rozważenia jest usunięcie białych znaków na końcu pliku podczas podstawiania poleceń
"$(cat file.txt)"
. Wszystkie obejścia tego problemu są stosunkowo złożone. Jeśli chcesz zachować znaki nowej linii na końcu pliku.txt, zobacz: https://stackoverflow.com/a/22607352/1091436źródło
file.txt
jest większa niż można zmieścić na liście argumentów doprintf
.Inny sposób użycia
sed
:Jeśli wiersz, który ma zostać dodany na początku, jest wielowierszowy:
źródło
sed -i '1ito be prepended' inFile
- czy jest to dozwolone tylko dla GNU sed?sed
poi
poleceniu następuje ukośnik odwrotny i znak nowej linii, a każdy wiersz wejścia oprócz ostatniego również kończy się ukośnikiem odwrotnym. GNUsed
dopuszcza skróty zgodne z pytaniami, o które pytasz, ale tylko GNUsed
to robi. 'Zgodnie z testami w Bash (w Ubuntu), jeśli zaczynasz od pliku testowego przez;
echo "Original Line" > test_file.txt
możesz wykonać;
echo "$(echo "New Line"; cat test_file.txt)" > test_file.txt
lub, jeśli wersja bash jest za stara dla $ (), możesz użyć lewych apostrofów;
echo "`echo "New Line"; cat test_file.txt`" > test_file.txt
i otrzymaj następującą zawartość pliku „test_file.txt”;
Brak pliku pośredniego, tylko bash / echo.
źródło
Innym dość prostym rozwiązaniem jest:
źródło
cat
rozwinięcia parametrów w podwójnych cudzysłowach jest całkiem dobrym powodem do odrzucenia . Ten kod dzieli zawartość pliku na słowa i przekazuje każde z tych słów jako oddzielny argument doecho
. Tracisz oryginalne granice argumentów, tracisz znaki nowej linii / tabulatory / itd., A ciągi takie jak\t
iw\n
oryginalnym tekście są zastępowane tabulatorami i znakami nowej linii zamiast pozostawać takie, jakie były.Jeśli lubisz vi / vim, to może być bardziej w Twoim stylu.
źródło
źródło
Poleciłbym zdefiniować funkcję, a następnie zaimportować ją i użyć w razie potrzeby.
Następnie użyj tego w ten sposób:
Zawartość twojego pliku będzie wtedy:
Mam zamiar użyć tego podejścia do wdrożenia aktualizacji dziennika zmian.
źródło