Jak wstawić tekst przed pierwszym wierszem pliku?

76

Rozglądałem się za sedpoleceniem, aby dodać tekst do pliku w określonym wierszu. Działa to dodając tekst po wierszu 1:

sed '1 a\

Ale chcę go dodać przed wierszem 1. Byłoby to:

sed '0 a\

ale pojawia się ten błąd: invalid usage of line address 0.

Jakieś sugestie?

Manolo
źródło
stackoverflow.com/questions/15157659/…
Léo Léopold Hertz 준영

Odpowiedzi:

101

Użyj opcji sedinsert ( i), która wstawi tekst w poprzednim wierszu.

sed '1 i\

Aktualizacja autora pytania:

Aby edytować plik na miejscu - w GNU sed- musiałem dodać -iopcję:

sed -i '1 i\anything' file

Również składnia

sed  -i '1i text' filename

Dla nie-GNU sed

Musisz nacisnąć klawisz powrotu natychmiast po ukośniku 1i\i po first_line_text:

sed -i '1i\
first_line_text
'

Zauważ też, że niektóre sedimplementacje inne niż GNU (na przykład ta w systemie macOS) wymagają argumentu dla -iflagi (użyj, -i ''aby uzyskać taki sam efekt jak w GNU sed).

podejrzenie
źródło
1
Nie działa bez -iopcji. Zaktualizuję twoją odpowiedź przed zaakceptowaniem.
Manolo,
1
dzięki. Z jakiego systemu operacyjnego korzystasz? Oryginalne rozwiązanie działało na OpenSuse 9.
podejrzenie
1
Ciekawy! Jestem na Lubuntu 13.10 i sed '1 i\this text is entered above the existing first line' filepracuje dla mnie.
2
Tutaj używanie sed (GNU sed) 4.2.2po prostu sed '1 i text to insert' -i filedziałało jak urok. Dzięki
ton
1
@FeRD Zobacz moją złą pozycję w rankingu awkponiżej. To powinno działać.
rudimeier
18

Echo służy do uzyskania tekstu. Cat nazwa pliku - drukuje plik w konsoli i> używa go do wysłania do innego pliku nazwa_pliku1, a następnie przenosimy nazwę pliku1 do nazwy pliku, aby wstawić tekst do pierwszego wiersza żądanego pliku.

  (echo "some text" && cat filename) > filename1 && mv filename1 filename
Ankit Shah
źródło
7
Proszę dać mi znać, dlaczego co następuje downvoted
Ankit Shah
1
Być może dlatego, że PO wspomina sed. Moim zdaniem nie zasługuje to na głosowanie w dół. To rozwiązanie było nawet najlepiej dopasowane do moich potrzeb, a potem zostało pozytywnie ocenione.
рüффп
Głosowałem. działa dla mnie na ksh.
arcee123
16

Możesz używać Vima w trybie Ex:

ex -sc '1i|ALFA BRAVO' -cx file
  1. 1 wybierz pierwszą linię

  2. i wstaw tekst i nowy wiersz

  3. x Zapisz i zamknij

Steven Penny
źródło
7

Chcesz wstawić tekst przed pierwszym wierszem, a nie dołączyć go później, więc użyj

sed '1 i\
your_text' your_file

Dokument tutaj może również pomóc:

cat /dev/stdin your_file <<EOI
Your text
goes here
EOI
Joseph R.
źródło
6

Za pomocą GNU awk> = 4.1:

awk -i inplace 'BEGINFILE{print "first line"}{print}' foo.sh

W przeciwieństwie do wszystkich sedodpowiedzi, działa to również na puste pliki.

rudimeier
źródło
inplacejest biblioteką i niestety pojawia się we wszystkich dystrybucjach awk. Dostaję komunikat „awk: fatal: nie można otworzyć pliku źródłowego„ w miejscu ”do czytania”GNU Awk 4.2.1, API: 2.0 (GNU MPFR 4.0.1, GNU MP 6.1.2)
vossad01
6
sed  -i '1i new_text' file_name

Jeśli nie określisz tej -iopcji, nie wyświetli żadnego błędu i wyświetli dane wyjściowe na standardowym terminalu, ale nie wstawi tekstu do pliku.

devi.
źródło
Pytanie nie dotyczy -izmiany.
don_crissti
Jak to wymyśliłeś? To jest odpowiedź na pytanie. Tak, jest podobny do przyjętej odpowiedzi, ale nie dokładnie taki sam.
G-Man
@ G-Man - można by argumentować, że szablon używany przez cas jest daleki od ideału, ale tak naprawdę jest podobny jak w prawie identycznym ... różnicą jest odstęp i fakt, że ten nie ma odwrotnego ukośnika. Jeśli chodzi o mnie, są one technicznie identyczne (ponieważ oba są gnu sedspecyficzne i tak się składa, że gnu sedakceptuje to ibez odwrotnego ukośnika). Jeśli inni myślą, że to uzasadnia osobną odpowiedź + głosowanie ... no cóż.
don_crissti
2

0aKomenda próbowano ma pracować ex, poprzednikvi :

printf '%s\n' 0a 'Anything you want to add' . x | ex file.txt

Samo printfpolecenie wydaje:

0a
Anything you want to add
.
x

Te 0aśrodki dołączania po 0th linii (czyli przed pierwszym wierszu).

Następny wiersz lub wiele wierszy to dosłowny tekst do dodania.

Sam .w linii kończy polecenie „append”.

Te xprzyczyny Ex, aby zapisać zmiany w pliku i wyjściu.

Dzika karta
źródło
1

Dziwi mnie, że w tym starym pytaniu nikt nie pokazał najczęstszego (i w tym przypadku dość prostego) polecenia sed:

$ sed  -i '1s/^/new_text\
/' file_name

Który działa w większości powłok i jest przenośny do kilku wersji sed.
Jeśli GNU sed jest dostępny, możesz użyć tego:

$ sed -i '1s/^/new_text\n' file_name

Różnica polega na tym, że GNU sed pozwala na użycie \nznaku nowej linii, a inne potrzebują literalnej nowej linii poprzedzonej odwrotnym ukośnikiem (który również działa w GNU sed).

Jeśli $'…'używana jest powłoka akceptująca składnię, możesz wstawić nową linię bezpośrednio, więc sed widzi, że nowa linia już tam jest:

$ sed -i $'1s/^/new_text\\\n/' file_name

Który działa dla większej liczby wersji sed.

Izaak
źródło
-1

Niestety, wszystkie powyższe odpowiedzi (głównie z sed) nie zadziałały dla mnie, ponieważ wszystkie zastąpiły pierwszą linię. Jestem na Ubuntu 16.04 LTSmaszynie. Oto moje obejście GNU Awk 4.0.2:

awk '{if(NR==1){$0="NEW_FIRST_LINE"$0; print $0} ;if(NR!=1){print $0}}' file_name
Splinter479
źródło
1
Nie jestem pewien, o czym mówisz ... Jest tylko jedna sedodpowiedź, która korzysta z zamiany, ale nie zastępuje istniejącej linii.
don_crissti
-1

Pierwszy i ostatni

Zakładam, że każdy, kto szukał sposobu wstawiania / dołączania tekstu na początku / końcu pliku, prawdopodobnie również musi wiedzieć, jak to zrobić.

cal |                            \
  gsed -E                        \
       -e     '1i\{'             \
       -e     '1i\  "lines": ['  \
       -e 's/(.*)/    "\1",/'    \
       -e '$s/,$//'              \
       -e     '$a\  ]'           \
       -e     '$a\}'

Wyjaśnienie

Dane calwyjściowe są przesyłane do gnu- sed(wywoływane gsedna macOS zainstalowanym przez brew.sh ) z rozszerzoną RegEx ( -E) i zastosowanymi 6 „skryptami” ( -e), a \dla zachowania czytelności łamane są wiersze linii . Skrypty 1 i 2 używają 1i\do „w wierszu 1 wstaw”. Skrypty 5 i 6 używają $a\do „w wierszu <last>, append”. Wyrównałem w pionie wyniki tekstowe, aby kod reprezentował oczekiwany wynik. Skrypty 3 i 4 wykonują podstawienia (te ostatnie dotyczą tylko „linii <last>”). Rezultatem jest konwersja danych wyjściowych komendy na poprawny JSON.

wynik

{
  "lines": [
    "    October 2019      ",
    "Su Mo Tu We Th Fr Sa  ",
    "       1  2  3  4  5  ",
    " 6  7  8  9 10 11 12  ",
    "13 14 15 16 17 18 19  ",
    "20 21 22 23 24 25 26  ",
    "27 28 29 30 31        ",
    "                      "
  ]
}
Bruno Bronosky
źródło
Chociaż nie głosowałem na twoje pytanie, zauważ, że mamy już kilka odpowiedzi, w tym jedną zaakceptowaną, które pokazują pożądany rezultat.
Jeff Schaller
@JeffSchaller Społeczność Stack Exchange nie jest forum. Jego cel wykracza poza pomoc w odblokowaniu PO. Celem jest zaszczepienie globalnej bazy wiedzy wieloma opcjami, na które poszukujący mogą natknąć się, szukając odpowiedzi. Podałem tytuł mojej odpowiedzi, aby pomóc użytkownikom rozpoznać użyteczność tej odpowiedzi, zanim klikną nawet wynik Google.
Bruno Bronosky
Mówię, że twoja odpowiedź nie zawiera żadnych nowych opcji (odpowiedzi) dla przyszłych czytelników tego pytania. Mamy już cztery odpowiedzi, które używają odmian 1ido wstawiania tekstu przed pierwszym wierszem. Ktoś z tym pytaniem musiałby wydobyć z odpowiedzi części, których potrzebują, aby rozwiązać problem. Pytania są bezpłatne, dlatego zapraszam do zadawania własnych pytań i udzielania odpowiedzi w celu udzielenia konkretnej odpowiedzi.
Jeff Schaller