Przekieruj dane wyjściowe ze wszystkich poleceń do pliku, a nie tylko na koniec


11

Chcę dodać nagłówek do pliku za pomocą echa, a następnie użyć polecenia, aby utworzyć resztę pliku. Oznacza to, że użyję dwóch osobnych poleceń.

Jak zapisać dane wyjściowe obu poleceń do pliku z przekierowaniem?

próbowałem

echo "header line" | cut -c 1-5 input_file > output_file

echo "header line"; cut -c 1-5 input_file > output_file

To tylko przekierowuje dane wyjściowe z polecenia cięcia.

Następujące polecenie działa, ale wydaje się niezdarne:

echo "header line" > output_file; cut -c 1-5 input_file >> output_file

Jaki jest sprytny sposób rozwiązania mojego problemu?

Odpowiedzi:


11

Problemem tutaj nie jest problem z przekierowaniem Linuksa; jest to raczej podstawowe nieporozumienie dotyczące działania rurociągu. Przekierowanie tutaj nie działa, ponieważ tylko cięcie jest w rzeczywistości drukowane na standardowe wyjście. stdout dla polecenia echo został potokowany do stdin cuta (który nie jest używany w tym przypadku, ponieważ określono plik).

echo "header line" > output_file && cut -c 1-5 input_file >> output_file

jest to, co chcesz, a nie nieeleganckie w ogóle (Wymieniłem swoje ;ze &&tak, że polecenie zostanie wykonane cięcie tylko jeśli nagłówek jest z powodzeniem napisane; w ten sposób, że nie będzie wykonywał jeśli nie masz uprawnień do tworzenia lub napisać do plik_wyjściowy ).

Możesz to również zrobić w podpowłoce, np.

(echo "header line"; cut -c 1-5 input_file) > output_file

ale nie ma w tym żadnej realnej korzyści, a przy bardziej złożonych przykładach może powodować problemy, jeśli nie jesteś zaznajomiony z zasięgiem podpowłoki.

Jeśli chcesz wyciąć, aby przejść przez standardowe wejście na standardowe wyjście, możesz spróbować:

echo "header line" | cut -c 1-5 - input_file

(Myślnik jest powszechnym skrótem dla standardowego wejścia)

Spowoduje to jednak również wykonanie operacji cięcia na stdin (co spowoduje powstanie linii nagłówka „header”). Trudno powiedzieć, czy tego właśnie chcesz, czy nie z pytania.


13

To czego szukasz to:

{ echo "header line"; cut -c 1-5 input_file; } > output_file
  • Ta składnia nie ma skutków ubocznych, ponieważ polecenia są wykonywane w bieżącej powłoce, a nie w podpowłoce
  • Istnieje wyraźne rozgraniczenie poleceń, które trafiają do pliku_wyjściowego
  • Skaluje się dobrze, ponieważ możesz przepisać w ten sposób:

{
  echo "header line"
  cut -c 1-5 input_file
  ... # insert new commands here
} > output_file

Jeśli chcesz, aby wyjście błędu przechodziło do tego samego pliku, możesz w ten sposób zmodyfikować ostatni wiersz:

} > output_file 2>&1

Podziękowania dla Oliviera Dulaca za przypomnienie tej wskazówki.

Jeśli chcesz, aby jakieś dane wyjściowe w bloku trafiły na ekran, możesz użyć tej składni:

{
  echo "header line"
  echo "this line doesn't go to output_file" > /dev/tty
  cut -c 1-5 input_file
} > output_file

+1: jest wyraźniejszy i wyraźnie identyfikuje, gdzie jest przekierowywany. Aby przekierować wszystko (w tym błędu MSG): { .... } > some_file 2>&1(będzie „sprać” jakis_plik nie sprać, ale zamiast dołączania do niej, po prostu zmienić. >W >>: { ... } >> some_file 2>&1)
Olivier DuLac

4

Aby zaokrąglić odpowiedzi, jest exec.

exec > output_file
echo "header line"
cut -c 1-5 input_file

+1: w skryptach bardzo często używa się tego (rzadziej w wierszu poleceń, ponieważ sprawy zaczynają się mylić ^^)
Olivier Dulac

Czy ktoś mógłby opracować to rozwiązanie? Widzę, co robi, ale nie rozumiem „exec” w tym kontekście. Ponadto wygląda na to, że musisz ponownie wyłączyć, jeśli reszta skryptu wymaga normalnego standardowego wyjścia.
Joe

1
kiedy używasz exec w skrypcie bez polecenia, możesz wykonać przekierowanie We / Wy w exec, które wpływa na bieżącą powłokę i wszystkie przyszłe elementy potomne.
Hildred

Dzięki. Nie widziałem tego wcześniej. Myślę, że będzie to bardzo przydatne.
Joe,
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.