Pytanie Jak połączyć stdin i string?


Jak połączyć stdin z ciągiem, jak to?

echo "input" | COMMAND "string"

i dostać

inputstring

76
2017-12-14 18:12


pochodzenie




Odpowiedzi:


Trochę zdziczałe, ale może to być najkrótsza droga do zrobienia tego, o co prosiłeś w pytaniu (użyj fajki do zaakceptowania stdout od echo "input" tak jak stdin do innego procesu / polecenia:

echo "input" | awk '{print $1"string"}'

Wydajność:

inputstring

Jakie zadanie dokładnie wykonujesz? Większy kontekst może pomóc w lepszym rozwiązaniu.

Aktualizacja - odpowiedź na komentarz:

@NoamRoss

Im bardziej idiotyczny sposób robienia tego, co chcesz, to:

echo 'http://dx.doi.org/'"$(pbpaste)"

The $(...) Składnia jest wywoływana podstawienie polecenia. W skrócie, wykonuje polecenia zawarte w nowej podpowłoce i zastępuje ją stdout wyjście do miejsca, gdzie $(...) został wywołany w powłoce rodzica. W efekcie otrzymasz:

echo 'http://dx.doi.org/'"rsif.2012.0125"

82
2017-12-14 18:24



Dzięki! Działa to świetnie. Dokładne zadanie, które próbuję wykonać, polega na pobraniu ciągu znaków ze schowka (DOI) i dodaniu do niego adresu URL, a więc robię to pbpaste | awk '{print "http://dx.doi.org/"$1}'i dostać http://dx.doi.org/10.1098/rsif.2012.0125 - Noam Ross
@NoamRoss zaktualizowana odpowiedź; wydaje się edytować;) - sampson-chen
@ sampson-chen, użyłbym '{print $0"string"}' złapać całość. - Roman Newaza
To faktycznie dołącza string do każdej linii. Próbować echo 'input'\n'another line' | awk '{print $0"string"}'. - tomekwi


posługiwać się cat - czytać ze standardowego wejścia i umieścić go $() wyrzucić spływ nowej linii

echo input | COMMAND "$(cat -)string"

Jednak dlaczego nie upuszczasz rury i nie chwytasz wyjścia lewej strony w zastępstwie komendy:

COMMAND "$(echo input)string"

40
2017-12-14 20:51



Oto praktyczny przykład: find ~ / other_program / lib -name "* .jar" | tr '\ n' ':' | echo "$ (cat -) ~ / java_app / classes" - Ashwin Jayaprakash
Działa to dla mnie w bashu, ale w zsh pojawia się "cat: -: Input / output error". Jakiś pomysł, co może to spowodować? - jaymmer


Często używam potoków, więc jest to łatwy sposób na prefiks i przyrostek stdin:

echo "my standard in" | cat <(echo "prefix... ") <(cat -) <(echo " ...suffix")
prefix... my standard in ...suffix

21
2017-10-15 03:04



Dzięki! To naprawdę bardzo fajny przykład użycia pipe i cat - Alex Ivasyuv
To powinna być najlepsza odpowiedź - Chris Koston
Dlaczego nie tylko: echo "my standard in" | echo -e "prefix\n$(cat -)\nsuffix"? Lub, bardziej czytelna wersja: echo "my standard in" | printf "%s\n%s\n%s\n" "prefix" "$(cat -)" "suffix" - MiniMax
@MiniMax Ponieważ odpowiedź działa dobrze w przypadku strumieni, będzie działać na dużych stdin. - anishpatel
@anishpatel Moja wersja będzie działać również na dużym stdin. Bez różnicy. - MiniMax


Możesz to zrobić za pomocą sed:

seq 5 | sed '$a\6'
seq 5 | sed '$ s/.*/\0 6/'

W twoim przykładzie:

echo input | sed 's/.*/\0string/'

9
2018-02-15 08:29





Jest kilka sposobów na osiągnięcie tego, ja osobiście uważam, że najlepsze jest:

echo input | while read line; do echo $line string; done

Innym przykładem może być "$" (znak końca linii) z "ciągiem" w poleceniu sed:

echo input | sed "s/$/ string/g"

Dlaczego wolę ten pierwszy? Ponieważ natychmiast łączy łańcuch do stdin, na przykład za pomocą następującego polecenia:

(echo input_one ;sleep 5; echo input_two ) | while read line; do echo $line string; done

natychmiast otrzymujesz pierwsze wyjście:

input_one string

a następnie po 5 sekundach otrzymasz inne echo:

input_two string

Z drugiej strony, używając "sed" najpierw wykonuje całą treść nawiasów, a następnie nadaje mu "sed", więc polecenie

(echo input_one ;sleep 5; echo input_two ) | sed "s/$/ string/g"

wypisze obydwie linie

input_one string
input_two string

po 5 sekundach.

Może to być bardzo przydatne w przypadku wykonywania połączeń z funkcjami, których wykonanie zajmuje dużo czasu i które wymagają ciągłej aktualizacji na temat wyjścia funkcji.


8
2017-12-05 12:05



Właściwie to sed opcja natychmiastowo przetwarza każdą linię wejścia. - tomekwi


Wiem, że jest to kilka lat za późno, ale możesz to zrobić za pomocą opcji xargs -J:

echo "input" | xargs -J "%" echo "%" "string"

A od tego jest xargs, możesz to zrobić na wielu liniach pliku naraz. Jeśli plik "names" ma trzy linie, takie jak:

Adam
Bob
Charlie

Mógłbyś:

cat names | xargs -n 1 -J "%" echo "I like" "%" "because he is nice"

4
2017-09-29 15:50



Wygląda fajnie z wyjątkiem -J nie wydaje się być standardowy / wspólny. W systemie Linux (gdzie xargs jest częścią GNU findutils) Otrzymuję błąd: xargs: invalid option -- 'J' Który system jest włączony? - arielf
-J jest dla wersji na Maca. Dla systemu Linux -I wykonuje tę samą funkcję. - user2635263
Dzięki! bardzo przydatne. Zwróć uwagę, że w systemie Linux ta uproszczona wersja działa równie dobrze: cat names | xargs -I% echo "I like % because he is nice" IOW: nie ma potrzeby -n 1 (xargs połączenia echo raz w każdym wierszu wejścia, ponieważ -I implikuje -L1) Ponadto wszystkie oddzielne cytowania arg wydaje się zbędne. - arielf


Polecenie, które wysłałeś, pobiera ciąg "input" użyje go jako strumienia standardowego COMMAND, który nie przyniesie oczekiwanych rezultatów, chyba że COMMAND wydrukuje najpierw zawartość stdin, a następnie wydrukuje argumenty wiersza poleceń.

Wygląda na to, że to, co chcesz zrobić, jest bardziej zbliżone do zastępowania poleceń.

http://www.gnu.org/software/bash/manual/html_node/Command-Substitution.html#Command-Substitution

W przypadku podstawiania komend możesz mieć linię poleceń w następujący sposób:

echo input `COMMAND "string"`

Najpierw oceni ona COMMAND z "string" jako dane wejściowe, a następnie rozszerzy wyniki wykonania poleceń na linię, zastępując to, co znajduje się pomiędzy znakami ".".


3
2017-12-14 18:23



i oczywiście @NaomRoss, chyba że musisz użyć powłoki Bourne'a lub masz inne zwariowane "przenośnościowe" uprawnienia, użyjesz nowoczesnego podstawiania poleceń jak echo input $(COMMAND "string")raczej niż odgłosy. Powodzenia wszystkim. - shellter


Działa również:

seq -w 0 100 | xargs -I {} echo "string "{}

Wygeneruje ciągi takie jak:

string 000
string 001
string 002
string 003
string 004

...


0
2018-04-01 18:31