Czy za pomocą zwykłego narzędzia wiersza poleceń, takiego jak sed lub awk, można łączyć wszystkie linie kończące się danym znakiem, np. Odwrotny ukośnik?
Na przykład, biorąc pod uwagę plik:
foo bar \
bash \
baz
dude \
happy
Chciałbym uzyskać ten wynik:
foo bar bash baz
dude happy
text-processing
awk
sed
perl
Cory Klein
źródło
źródło
cpp
:)sed
FAQOdpowiedzi:
krótsze i prostsze rozwiązanie sed:
lub jednowierszowy, jeśli używasz GNU
sed
:źródło
sed
:) ... Dołączasz każdą linię bezpośrednio do przestrzeni wzorów, a kiedy pojawia się linia „normalnie zakończona”, cała przestrzeń wzorów spada i auto drukuje (ponieważ nie ma opcji -n) ... fajnie! .. +1sed -e :a -e '/\\$/N; s/\\\n//; ta'
Jest to prawdopodobnie najłatwiejsze w Perlu (ponieważ perl jest podobny do sed i awk, mam nadzieję, że jest dla ciebie akceptowalny):
źródło
Oto niesamowite rozwiązanie. Jeśli linia kończy się na a
\
, usuń ukośnik odwrotny i wydrukuj linię bez kończącej nowej linii; w przeciwnym razie wydrukuj linię z kończącym znakiem nowej linii.Nie jest też tak źle w sed, chociaż awk jest oczywiście bardziej czytelny.
źródło
To nie jest odpowiedź jako taka. Jest to kwestia poboczna
sed
.W szczególności musiałem
sed
rozdzielić polecenie Gillesa kawałek po kawałku, aby to zrozumieć ... Zacząłem pisać na ten temat kilka uwag, a potem pomyślałem, że może się tu przydać komuś ...więc oto jest ... skrypt Gillesa sed w udokumentowanym formacie:
źródło
Jeszcze innym powszechnym narzędziem wiersza poleceń byłoby
ed
, które domyślnie modyfikuje pliki w miejscu, a zatem pozostawia uprawnienia do plików niezmodyfikowane (więcej informacji na ten temat możnaed
znaleźć w rozdziale Edytowanie plików za pomocą edytora tekstu ed ze skryptów )źródło
Wykorzystując fakt, że
read
w powłoce zinterpretuje odwrotne ukośniki, gdy jest używany bez-r
:Pamiętaj, że spowoduje to również interpretację wszelkich innych ukośników odwrotnych w danych.
źródło
a\\b\\\\\\\\\\\c
Proste (r) rozwiązanie, które ładuje cały plik do pamięci:
Lub jeszcze krótki, który działa rozumiejąc (wyjściowe) linie (składnia GNU):
W jednym wierszu (składnia POSIX):
Lub użyj awk (jeśli plik jest zbyt duży, aby zmieścić się w pamięci):
źródło
Wersja Mac oparta na rozwiązaniu @Giles wyglądałaby tak
Główna różnica polega na tym, jak reprezentowane są nowe linie, a łączenie ich w jedną linię powoduje jej przerwanie
źródło
Możesz użyć cpp, ale tworzy kilka pustych wierszy, w których scalał dane wyjściowe, i pewne wprowadzenie, które usuwam za pomocą sed - być może można to również zrobić za pomocą flag cpp i opcji:
źródło
cpp
jest to rozwiązanie? W twoim przykładzieecho
ciąg z podwójnymi cudzysłowami już wyświetla wyprostowany tekst, więc niecpp
ma sensu. (Dotyczy to również twojegosed
kodu.) Jeśli wstawisz ciąg w cudzysłowie,cpp
po prostu usuwa ukośniki odwrotne, ale nie łączy wierszy. (Konkatenacja zcpp
działałaby, gdyby nie było miejsca przed odwrotnym ukośnikiem, ale wtedy osobne słowa byłyby łączone bez separatorów.)cpp
ten sposób wciąż nie łączy ze sobą wierszy. A użyciesed
jest zdecydowanie niepotrzebne. Użyjcpp -P
: „-P
Hamuj generowanie znaczników linii w danych wyjściowych z preprocesora.” - man cppcpp: “-P: No such file or directory cpp: warning: '-x c' after last input file has no effect cpp: unrecognized option '-P:' cpp: no input files
cpp --version
ujawniacpp (Ubuntu 4.4.3-4ubuntu5.1) 4.4.3
- co? Ubuntu łata cpp? Czemu? Spodziewałbym się przeczytać GNU ...cpp
rzeczywiście łączy linie i pozostawia pewne spacje. Jeszcze bardziej interesujące, ta sama wersja 4.4.3-4ubuntu5.1 tutaj akceptuje-P
. Jednak tylko eliminuje znaczniki linii, puste linie pozostają.