Jak wydrukować wydruk wielowierszowy w tym samym wierszu?

16

Czy istnieje metoda drukowania wydruku wieloliniowego (pojedynczego wydruku) na tej samej linii?

Na przykład jeśli wynikiem jest:

abc
def
qwerty

Czy można wydrukować:

abcdefqwerty 
Shrinidhi Kulkarni
źródło

Odpowiedzi:

13

Możesz usunąć wszystkie wystąpienia znaków z danego zestawu za pomocą tr -d. Aby usunąć znak nowej linii, użyj:

tr -d '\n'

Jak zawsze możesz używać przekierowania wejścia i wyjścia oraz potoków do odczytu lub zapisu do plików i innych procesów.

Jeśli chcesz zachować ostatnią nową linię, możesz po prostu dodać ją z powrotem za pomocą echolub printf '\n', np .:

cat file1 file2... | { tr -d '\n'; echo; } > output.txt
David Foerster
źródło
10

Wiele sposobów. Aby to zilustrować, zapisałem twój przykład w file:

$ cat file | tr -d '\n'
abcdefqwerty$ 
$ cat file | perl -pe 's/\n//'
abcdefqwerty$ 

To usuwa wszystkie znaki nowego wiersza, w tym ostatni. Zamiast tego możesz chcieć:

$ printf "%s\n" "$(cat file | perl -pe 's/\n//')"
abcdefqwerty
$ printf "%s\n" "$(cat file | tr -d '\n')"
abcdefqwerty
terdon
źródło
Myślę, że kombinacja printf+ cat+ perljest znacznie lepiej obsługiwana przez perl -pe 's/\n//;END{printf "\n"}' input.txt Pojedynczy proces, bez podstawiania poleceń i mieszania się z cudzysłowami oraz bez UUOC. Być może.
Sergiy Kolodyazhnyy
7

Możesz przesyłać swoje wyjście multilinii awk

awk '{printf "%s",$0} END {print ""}'

lub użyj sed:

sed ':a;N;$!ba;s/\n//g'

Przykładowy przebieg

$ echo -e "1\n2\n3\n4" | awk '{printf "%s",$0} END {print ""}'
1234
$ echo -e "1\n2\n3\n4" | sed ':a;N;$!ba;s/\n//g'              
1234

Dalsza lektura: usuń łamanie linii za pomocą AWK · serverfault.SE

deser
źródło
4

Również, your_command | paste -sd ''który zachowuje końcowy znak nowej linii.

Glenn Jackman
źródło
2

Jeśli chcesz do tego użyć Perla, możesz użyć jego chompfunkcji:

perl -pe chomp

Więcej informacji dla zainteresowanych.

Jako kolejne argumenty możesz przekazać jedną lub więcej nazw plików.

perl -pe chomp file1 file2 file3

W niektórych przypadkach możesz tego nie chcieć , ale zamiast tego możesz przesłać potokiem lub przekierować do tego polecenia. (Te umiejętności - i to zastrzeżenie - wszystkie odnoszą się również do każdego innego perl -plub perl -nopartego na rozwiązaniu rozwiązania).

Jeśli więc chcesz przetworzyć dane wyjściowe z działania some-command:

some-command | perl -pe chomp

Jest to potencjalnie szybsze niż polecenie Perla w odpowiedzi terdona . Znaki nowej linii (reprezentowane przez \n) pojawiają się tylko na końcu linii w tej sytuacji - ponieważ są one tym, czego Perl używa do decydowania, gdzie kończy się każda linia. s/\n//przeszukuje całą linię w poszukiwaniu nowych linii, a chomppo prostu usuwa tę na końcu (jeśli istnieje, ponieważ ostatnia linia może, ale nie musi).

Wydajność może nie być głównym powodem preferowania chomp. perlPolecenia w odpowiedzi terdon za byłyby tylko nieznacznie wolniej, chyba że jesteś przetwarzania ogromny plik z bardzo długich kolejkach. A jeśli potrzebujesz prędkości, droga Davida Foerstera jest prawdopodobnie prawdopodobnie szybsza. chompjest jednak dokładnie odpowiednim narzędziem do tego, jeśli używasz Perla, i myślę, że intencja chompjest wyraźniejsza niż w przypadku s/\n//. Ostatecznie prawdopodobnie nie ma obiektywnej odpowiedzi na pytanie, która z nich jest lepsza.

Drukowanie końcowej nowej linii.

Odradzam jednak stosowanie substytucji poleceń ( $( )) tylko po to, aby upewnić się, że drukowany jest znak nowej linii. O ile tekst, który przetwarzasz, nie jest krótki, jest to prawdopodobnie dość powolne - musi zebrać cały tekst na raz, a następnie wydrukować - i utrudnia zrozumienie twojego polecenia. Zamiast tego możesz zrobić, jak sugerował David Foerster, i pobiec echolub printf '\n'później.

perl -pe chomp; echo

Jeśli przesyłasz strumieniowo z lub (jak pokazuje David Foerster) przekierowując z tego polecenia, możesz je zawrzeć, { ;}aby dane wyjściowe obu poleceń zostały zebrane razem. Jeśli drukujesz go tylko na terminalu, możesz uruchomić go dokładnie tak, jak pokazano powyżej. Działa to nawet wtedy, gdy przesyłasz lub przekierowujesz do polecenia, ponieważ echo/ printf '\n'tak naprawdę nie czyta żadnych danych wejściowych. Oznacza to, że działa:

some-command | perl -pe chomp; echo

Tutaj nie można po prostu usunąć { ;}:

{ perl -pe chomp; echo; } | some-other-command

Lub, jeśli wolisz, możesz sam perlwydrukować ostatnią nową linię. Podobnie jak w przypadku dołączania poleceń perli , ta metoda działa nawet wtedy, gdy przepływasz lub przekierowujesz z niej (i, podobnie jak wszystkie podejścia, działa również, gdy do niej przepływasz):echo{ ;}

perl -wpe 'chomp; END { print "\n" }'

Zauważ, że polecenie w odpowiedzi terdona działa dobrze również z tymi metodami drukowania ostatniego znaku nowej linii. Na przykład:

perl -pe 's/\n//'; echo
perl -pe 's/\n//; END { print "\n" }'
Eliah Kagan
źródło
perl -wpe 'chomp; END { print "\n" } to ten sam proces, niewielka przewaga nad dodaniem echa końcowego
Sergiy Kolodyazhnyy
1

Używając tylko powłoki:

while IFS= read -r line || [ -n "$line" ]; do printf "%s"  "$line"; done < inputfile.txt
Sergiy Kolodyazhnyy
źródło
1

Ta odpowiedź ma rozwiązanie problemu, który próbujesz stworzyć: Dlaczego bash usuwa \ n w $ (plik cat)?

Jeśli wpiszesz cat myfile.txt, zobaczysz:

abc
def
ghi

Ale jeśli wpiszesz echo $(cat myfile.txt), zobaczysz:

abc def ghi

Zauważ, że ta metoda wstawia spację, w której kiedyś były oddzielne nowe linie. Dzięki temu wynik jest łatwiejszy do odczytania, ale nie ściśle odpowiada zakresowi pytań.

WinEunuuchs2Unix
źródło
0

Jeśli korzystasz z Bash, możesz to zrobić bez zewnętrznego narzędzia.

x=($(echo line1; echo line2))
echo "${x[@]}"

Wynik:

line1 line2

Pierwsze polecenie przekształca wieloliniowe dane wyjściowe w tablicę, drugie polecenie rozszerza tablicę na wiele argumentów w jednym wierszu.

osexp2003
źródło