Jak różnicować plik i dane wyjściowe z polecenia?


32

Zwykle piszesz:

diff file1 file2

Ale chciałbym różnicować plik i dane wyjściowe z polecenia (tutaj robię polecenie trywialnym):

diff file1 <(cat file2 | sort)

Ok, to działa, gdy wprowadzę to ręcznie w wierszu poleceń powłoki, ale kiedy wstawię dokładnie ten sam wiersz w skrypcie powłoki, a następnie uruchomię skrypt, pojawia się błąd.

Pytanie brzmi: jak to zrobić poprawnie?

Oczywiście chciałbym uniknąć zapisywania danych wyjściowych do pliku tymczasowego.

Odpowiedzi:


39

Podejrzewam, że twój skrypt i twoja powłoka są różne. Być może masz #!/bin/shna górze skryptu jako tłumacz, ale używasz go bashjako osobistej powłoki. Możesz dowiedzieć się, jaką powłokę uruchamiasz w terminalu, uruchamiając echo $SHELL.

Łatwiejszym sposobem na zrobienie tego, co powinno działać w większości powłok, byłoby użycie przekierowania potoku zamiast podanego operatora odczytu plików. Symbol „-” jest standardową nomenklaturą do odczytu STDIN i często może być używany jako zamiennik nazwy pliku na liście argumentów:

cat file2 | sort | diff file1 -

Lub, aby uniknąć bezużytecznego użycia kota :

sort < file2 | diff file1 -

Ach, jesteś dobry, naprawdę, nie sprawdziłem, czy sh to bash, czy nie. Dziękuję bardzo za rozwiązanie.
greenoldman

Jest to plik różnicujący ze standardowym wyjściem. Jak teraz różnicować standardowe wyjście z plikiem? Mam na myśli odwrotny kierunek. jest -Rw przypadku użyciagit diff --no-index
Nakilon

@Nakilon byłoby po prostu zmienić kolejność argumentów: diff - file1.
Caleb

Fajne. To nie zadziałało git diff.
Nakilon,

@Nakilon Oczywiście, że nie, dlaczego miałoby to być? git diffjest zupełnie inną bestią i działa na odniesieniach do obiektów globu w swoim wewnętrznym indeksie, a nie w plikach; diffdziała na systemie plików. -Składnia jest po prostu zapłacić za cukier syntaktyczny /dev/stdin, pliku reprezentującego strumienia stdin. Dlatego dlaczego diffmożna go używać jako zamiennika nazwy pliku. Tymczasem git diffnie szuka plików, szuka obiektów, więc musisz przekazać coś, co rozpoznaje. Nie używaj go do porównywania plików, użyj diffdo tego.
Caleb

-4

Zakres standardowego wejścia to sam skrypt, więc po prostu umieść swój kod w blocku w następujący sposób:

{
  diff file1 <(sort file2)
}

W ten sposób zakres STDIN znajduje się w bloku.

Próbowałem i to działa.


To nie jest funkcja, to jest blok i nie robi żadnej różnicy.
Gilles „SO- przestań być zły”,

@Gilles Thx za korektę. BTW Próbowałem sam i to działa. Czy ty?
jutro

3
Blok nie ma żadnego wpływu na ważność <(…)konstrukcji. Twój skrypt będzie działał, czy nie, w zależności od tego, czy uruchomisz go w powłoce, która obsługuje, <(…)czy nie (ksh93 / bash / zsh vs Bourne / ash / kshk88). Odpowiedź Caleba to wszystko.
Gilles 'SO - przestań być zły'

1
@ Gilles ok, dziękuję za wyjaśnienie.
tmow
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.