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.