Czy wyświetlać nazwę pliku na początku każdego wiersza podczas dopasowywania wielu plików jednocześnie?

14

czy podczas dostosowywania wielu plików jednocześnie, jak pokazano poniżej, czy jest jakiś sposób, aby pokazać nazwę pliku na początku każdej linii?

tail -f one.log two.log

prąd wyjściowy

==> one.log <==
contents of one.log here...
contents of one.log here...

==> two.log <==
contents of one.log here...
contents of two.log here..

Szukasz czegoś podobnego

one.log: contents of one.log here...
one.log: contents of one.log here...
two.log: contents of two.log here...
two.log: contents of two.log here...
Mtk
źródło
Możesz spojrzeć na -vopcję (pełną) ogona. To może nie do końca pasować do twojego zapytania, ale jest początkiem.
rahul
Myślę, że multitail może to zrobić
Gilles „

Odpowiedzi:

7
tail  -f ...your-files | 
    awk '/^==> / {a=substr($0, 5, length-8); next}
                 {print a":"$0}'

\ dzięki {don_cristti}

JJoao
źródło
@don_crissti, dziękuję! (1) plik vs - nie więcej wina do mojego kieliszka! (2) dobry pomysł. Zaczynam robić coś takiego, ale niechętnie powiedziałem sobie: „nikt nie zrobi ogona z plikami ze spacjami” :) - Wykorzystam twoje doskonałe sugestie.
JJoao
możesz wyjaśnić długość-8? dlaczego tutaj jest 8, wiem tylko 8 prac.
Shicheng Guo
1
tail -n 1 * .txt | awk '/ ^ ==> / {a = substr (0, 5, długość-8); dalej} {wydrukuj, $ 1} '| awk '2 $> 0 {if (2 $! ~ / chrY /) print 1 $}' | xargs -I {} qsub {}
Shicheng Guo
@ShichengGuo, 8 = długość („==>”) + długość („<==”)
JJoao
1
zaskakująco / zadziwiająco twoje magiczne awkrozwiązanie joojoo działa!
Trevor Boyd Smith
6

Krótka odpowiedź

GNU Parallel ma zestaw fajnych opcji, które sprawiają, że naprawdę łatwo jest robić takie rzeczy:

parallel --tagstring "{}:" --line-buffer tail -f {} ::: one.log two.log

Dane wyjściowe będą:

one.log: zawartość one.log tutaj ...
one.log: zawartość one.log tutaj ...
two.log: zawartość two.log tutaj ...
two.log: zawartość two.log tutaj ...

Więcej wyjaśnień

  • Opcja oznacza --tagstring=strkażdą linię wyjściową ciągiem str . Ze parallel strony podręcznika :
--stragstring str
                Oznacz linie sznurkiem. Każda linia wyjściowa będzie poprzedzona znakiem
                str i TAB (\ t). str może zawierać ciągi zastępujące, takie jak {}.

                --tagstring jest ignorowany przy użyciu opcji -u, --onall i --nonall.
  • Wszystkie wystąpienia {}zostaną zastąpione argumentami równoległymi, które w tym przypadku są nazwami plików dziennika; tj. one.logi two.log(wszystkie argumenty po :::).

  • Opcja --line-bufferjest wymagana, ponieważ wyjście polecenia (np. tail -f one.logLub tail -f two.log) zostanie wydrukowane, jeśli polecenie to zostanie zakończone. Ponieważ tail -fbędzie czekać na powiększenie pliku, konieczne jest wydrukowanie danych wyjściowych w trybie liniowym, który to --line-bufferrobi. Znów ze parallel strony man :

- bufor buforowy (testy alfa)
                Wyjście buforowe na podstawie linii. --group zachowa wyjście
                razem dla całej pracy. --ungroup pozwala mieszać dane wyjściowe
                połowa linii pochodzi z jednej pracy, a połowa linii pochodzi z
                inna praca. - bufor-linii pasuje między tymi dwoma: GNU równolegle
                wypisze pełną linię, ale pozwoli na mieszanie linii
                różne prace.
rysownik
źródło
2

Jeśli tailnie jest to obowiązkowe, możesz użyć grepdo osiągnięcia tego:

grep "" *.log

Spowoduje to wydrukowanie nazwy pliku jako prefiksu każdej linii wyjściowej.

Dane wyjściowe ulegają awarii, jeśli zostaną *.logrozwinięte tylko do jednego pliku. Pod tym względem:

grep '' /dev/null *.log
serenesat
źródło
Muszę pokazać nazwę pliku na wyjściu tail -fnie grep.
Mt
@serenesat to po prostu wydrukuje całą zawartość plików, prawda? OP poprosił o wydrukowanie nazwy pliku, gdy określono ogon
rahul,
możesz też po prostu zrobić --with-filenamelub -Hzawsze wymusić dodanie nazwy pliku.
Trevor Boyd Smith
bardzo podoba mi się ta odpowiedź! robi dokładnie DOKŁADNIE to, czego potrzeba w przypadku rozwiązania o długości 13 znaków. w przeciwieństwie do trudnego awkrozwiązania lub parallelktóre nie jest zainstalowane.
Trevor Boyd Smith
Jedynym problemem jest to, że jeśli twoje pliki dziennika mają długość 1 miliona linii. wtedy twój grep wyśle ​​spam 1 milion linii na konsolę (lub przez ssh) ...
Trevor Boyd Smith
0

Moim pomysłem byłoby utworzenie jednego pliku ze scalonymi dziennikami z kilku plików, jak ktoś tutaj zasugerowany i dodanie nazw plików:

$ tail -f /var/log/syslog | sed -u -E 's,(^.+$),/var/log/syslog: \1,g' >> /tmp/LOG &&
$ tail -f /var/log/Xorg.0.log | sed -u -E 's,(^.+$),/var/log/Xorg.0.log: \1,g' >> /tmp/LOG &&
$ tail -f /tmp/LOG
Arkadiusz Drabczyk
źródło
0

Coś z xargsi sedmoże działać:

$ xargs -I% -P0 sh -c "tail -f % | sed s/^/%:/g" <<EOT
one.log
two.log
EOT
FloHimself
źródło