Przekierowanie zawartości pliku do polecenia „echo”


41

Mam plik o nazwie, my_file.txtktórego treść jest tylko ciągiem Hello. Jak mogę przekierować jego treść do polecenia echo?

Wiem, że mam polecenia less, cat, more... ale muszę to zrobić z echo.

Próbowałem tego:

$ cat my_file.txt | echo

a także to:

$ echo < my_file.txt

Ale w obu przypadkach pojawia się tylko puste miejsce na standardowym wyjściu, a nie zawartość my_file.txt.

Jak mogłem to zrobić?


7
Dlaczego nalegasz na używanie echo?
— Kevin

7
@Kevin, prawdopodobnie w końcu chce rozwinąć sekwencje specjalne ANSI C ( \n, b...) w pliku, co byłoby poprawnym użyciem echo(przynajmniej standardu echo). Lub prawdopodobnie chce zrozumieć, dlaczego to nie działa w ten sposób. W każdym razie nie ma powodu, by głosować za IMO.
— Stéphane Chazelas,

3
Przybyłem tutaj, ponieważ byłem ciekawy, dlaczego to nie działa, gdy echo <file.txt. Odpowiedź na pytanie w SE wydaje się rozsądna, odpowiedź była bardzo pomocna. +1 ode mnie
— neuronet

Odpowiedzi:


53

Możesz przekierować wszystko, co chcesz, echoale nic z tym nie zrobi. echonie odczytuje standardowego wejścia. Wszystko, co robi, to zapisywanie na standardowe wyjście argumentów oddzielonych znakiem spacji i zakończonych znakiem nowego wiersza (oraz z niektórymi echoimplementacjami z pewnymi sekwencjami ucieczki w nich rozwiniętymi i / lub argumentami zaczynającymi się od -ewentualnie traktowanych jako opcje).

Jeśli chcesz echowyświetlić zawartość pliku, musisz przekazać tę treść jako argument echo. Coś jak:

echo "$(cat my_file.txt)"

Należy zauważyć, że $(...)paski znak nowej linii spływu s od wyjścia tego catpolecenia i echododaje jeden plecy.

Zauważ też, że oprócz „ zshnie” nie można przekazać znaków NUL w argumentach polecenia, więc powyższe zwykle nie będzie działać z plikami binarnymi. yashusunie również bajty, które nie stanowią części prawidłowych znaków.

Jeśli powodem chce zrobić to dlatego, że chcesz echo, aby rozwinąć \n, \b, \0351... sekwencje w pliku (jako zgodne z normą UNIX echoimplementacje zrobić, ale nie wszystkie ), to wolisz używać printfzamiast :

printf '%b\n' "$(cat my_file.txt)"

W przeciwieństwie do echotego, ten jest przenośny i nie będzie miał problemów, jeśli zawartość pliku zaczyna się od -.


Jako alternatywę do $(cat file), z ksh, zsha bash, można również zrobić:$(<file) . Jest to specjalny operator, w którym powłoka w przeciwieństwie do catodczytu zawartości pliku stanowi uzupełnienie. Nadal usuwa końcowe znaki nowej linii i dławiki na bajtach NUL z wyjątkiem zsh. W bashtym nadal widnieje dodatkowy proces. Zauważ również, że jedną różnicą jest to, że nie dostaniesz żadnego błędu, jeśli spróbujesz odczytać plik katalogu typu w ten sposób. Ponadto, chociaż $(< file)jest wyjątkowy, $(< file; other command)nie jest (w zsh, gdy nie emuluje innej powłoki, która nadal rozszerzałaby zawartość file, uruchamiając polecenie niejawne $READNULLCMD (zwykle pager)).


3
Zarówno w bash i zsh można pominąć cati po prostu powłoka czytać go bezpośrednio: echo "$(<my_file.txt)".
— Kevin

1
Tak, z ksh , zsh i bash możesz korzystać $(<filename).
— Dimitre Radoulov

Dziękuję bardzo, tego potrzebowałem i zadziałało! :-)
— danielmbcn

@Kevin, Dimitre, dodano teraz.
— Stéphane Chazelas

4

Dodając do innych odpowiedzi, możesz również spróbować przekierować wejście zamiast cat

echo $(<my_file.txt)

lub

echo `<my_file.txt`

$()i `` wykonują to samo, uruchamiają polecenia w swoim zakresie i przekazują dane wyjściowe do powłoki tak, jakby była podana przez użytkownika jako dane wejściowe. Jedyną różnicą między tymi dwoma jest to, że $ () może być rekurencyjny i `` nie może być rekurencyjny.


2

Prosta odpowiedź: nie możesz. echo(czy to wbudowany w powłokę, czy zwykły plik binarny) nie przetwarza standardowego wejścia - jest tylko jeden sposób.


Pytanie brzmi, dlaczego tak naprawdę chcesz to zrobić?
— peterph

2

Jak powiedziano

Jeśli chcesz echowyświetlić zawartość pliku, musisz przekazać tę treść jako argumentecho

Na przykład możesz to zrobić w następujący sposób xargs(biorąc pod uwagę, że musisz włączyć interpretację ucieczek odwrotnego ukośnika ):

$ cat my_file.txt | xargs echo -e

Lub po prostu to, o co prosiłeś (bez interpretacji sekwencji ucieczki ):

$ cat my_file.txt | xargs echo

Zauważ jednak, że podczas używania xargs echo(tak samo jak xargsbtw jak echodomyślne polecenie), uruchomione zostanie echopolecenie z systemu plików, a nie wbudowane echopolecenie powłoki . Zauważ też, że xargsoczekuje danych wejściowych w bardzo specyficznym formacie (gdzie spacje, znaki nowej linii, cudzysłowy, odwrotne ukośniki mają specjalne znaczenie). catnie ma większego sensu tu jest tylko jeden plik do łączenia (tak samo jak < file.txt xargs echoZauważ, że Unix zgodny. echos zrobić ekspansję ucieczki backslash domyślnie i wyjście -ena echo -e.
— Stéphane Chazelas

0

W bash powinny działać również następujące elementy:

echo `cat my_file.txt`

Część w backticks jest zastępowana przez dane wyjściowe tego polecenia, tj. W tym przypadku jest zastępowana przez zawartość pliku.


To prawda, że ​​backticks działają jak $( . . . ). Ludzie, którzy używają $()zwykle wolą je, ponieważ można je zagnieżdżać. To pytanie jest jednak stare, o wiele bardziej satysfakcjonujące jest odpowiadanie na pytania, na które jeszcze nie ma odpowiedzi!
— Law29

Nie do końca. Jest subtelna różnica. Gdy używana jest forma odwrotnego tyknięcia, odwrotny ukośnik zachowuje swoje dosłowne znaczenie, chyba że po nim następuje $, `lub \. Pierwszy tyknięcie nie poprzedzone ukośnikiem kończy polecenie. Podczas korzystania z formularza $ (,,,) wszystkie znaki między nawiasami tworzą polecenie.
— fpmurphy

Ponieważ to zastąpienie polecenia nie jest cytowane, zostanie do niego zastosowany operator split + glob. Na przykład, jeśli my_file.txtzawiera *, spowoduje to wydrukowanie listy nazw plików w bieżącym katalogu.
— Stéphane Chazelas
Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.