Как пропустить первый столбец в выводе терминала и параллельно записать вывод (вместе с пропущенным первым столбцом) в файл, используя unix? - PullRequest
0 голосов
/ 18 мая 2018

Я застрял в следующем сценарии.

Я добавил их в один скрипт с именем small_script.sh

#!/bin/bash

uname
uname -r
uname -a
pwd

Мне нужна метка времени в секундах для каждой строки, отображаемой втерминал и необходимо записать в файл. Следовательно, я реализовал, как показано ниже:

./small_script.sh | while read R; do echo "$(date +%s) $R"; done | tee output.txt

1526635998 Darwin
1526635998 17.4.0
1526635998 Darwin C02V41QWHV2R 17.4.0 Darwin Kernel Version 17.4.0 ..
1526635998 /Users/home/duraja

Теперь мой запрос я ищу вывод в терминале, где первый столбец (дата в секундах) не отображается, ноПервый столбец (дата в секундах) должен быть в моем текстовом файле.

Пример ожидаемого вывода ..

Вывод терминала должен отображать

Darwin
17.4.0
Darwin C02V41QWHV2R 17.4.0 Darwin Kernel Version 17.4.0 ..
/Users/home/duraja

Вывод текстового файла должен отображать

1526635998 Darwin
1526635998 17.4.0
1526635998 Darwin C02V41QWHV2R 17.4.0 Darwin Kernel Version 17.4.0 ..
1526635998 /Users/home/duraja

Как мне добитьсяЭто ?Пожалуйста, предложите.

Ответы [ 5 ]

0 голосов
/ 19 мая 2018

Вы можете разделить секунды от данных, используя cut.Я изменил R на строчные буквы, использовал параметр -r для read и использовал printf, это не по теме улучшения.

./small_script.sh |while read -r r; do
   printf "%s %s\n" $(date +%s) "$r"
done | tee output.txt | cut -d" " -f2-

Вы уже можете разделить вывод в цикле.
Вы можете писать в терминал, используя stderr

./small_script.sh |while read -r r; do
   >2 printf "%s\n" "$r"
   printf "%s %s\n" $(date +%s) "$r"
done > output.txt 

Недостатком является то, что вывод поступает в stderr, поэтому перенаправление вывода терминала или использование |more отличается от ожидаемого.
Когда вы перенаправляете строки с секундами внутри цикла, вы должны сначала удалить выходной файл (если он существует)

test -f output.txt && rm -f output.txt
./small_script.sh |while read -r r; do
   printf "%s\n" "$r"
   printf "%s %s\n" $(date +%s) "$r" >> output.txt
done 
0 голосов
/ 18 мая 2018

См. https://unix.stackexchange.com/questions/169716/why-is-using-a-shell-loop-to-process-text-considered-bad-practice для некоторых причин, чтобы избежать этого с помощью цикла оболочки.

Предполагая, основываясь на цикле в вашем вопросе, что вам нужна временная метка, когдакаждая выходная строка создается, а не временная метка, когда создается первая строка (что было бы тривиально), и с учетом этого сценария оболочки:

$ cat ./small_script.sh
uname
sleep 1
uname -r
sleep 1
uname -a
sleep 1
pwd

С shell и xargs (могут быть некоторые ошибки)/ gnu-isms там):

$ ./small_script.sh | xargs -d$'\n' -I {} sh -c 'printf "%s\n" "{}"; printf "%s %s\n" "$(date +"%s")" "{}" >&2' 2>outfile1
CYGWIN_NT-6.1
2.9.0(0.318/5/3)
CYGWIN_NT-6.1 Foo 2.9.0(0.318/5/3) 2017-09-12 10:18 x86_64 Cygwin
/home/Ed

$ cat outfile1
1526673758 CYGWIN_NT-6.1
1526673759 2.9.0(0.318/5/3)
1526673760 CYGWIN_NT-6.1 Foo 2.9.0(0.318/5/3) 2017-09-12 10:18 x86_64 Cygwin
1526673761 /home/Ed

С GNU awk для функций времени:

$ ./small_script.sh | awk '{print systime(), $0 > "outfile2"} 1'
CYGWIN_NT-6.1
2.9.0(0.318/5/3)
CYGWIN_NT-6.1 Foo 2.9.0(0.318/5/3) 2017-09-12 10:18 x86_64 Cygwin
/home/Ed

$ cat outfile2
1526673256 CYGWIN_NT-6.1
1526673257 2.9.0(0.318/5/3)
1526673258 CYGWIN_NT-6.1 Foo 2.9.0(0.318/5/3) 2017-09-12 10:18 x86_64 Cygwin
1526673259 /home/Ed

и с любым awk:

$ ./small_script.sh | awk '{cmd="date +\"%s\""; date=( (cmd | getline line) > 0 ? line : "ERR"); close(cmd); print date, $0 > "outfile3"} 1'
CYGWIN_NT-6.1
2.9.0(0.318/5/3)
CYGWIN_NT-6.1 Foo 2.9.0(0.318/5/3) 2017-09-12 10:18 x86_64 Cygwin
/home/Ed

$ cat outfile3
1526673404 CYGWIN_NT-6.1
1526673405 2.9.0(0.318/5/3)
1526673406 CYGWIN_NT-6.1 Foo 2.9.0(0.318/5/3) 2017-09-12 10:18 x86_64 Cygwin
1526673407 /home/Ed
0 голосов
/ 18 мая 2018

Поскольку вы не указали в своем сообщении полное требование, пример ввода или пример вывода, пожалуйста, попробуйте следующее (на основе предоставленного кода и вопроса), в котором первый столбец будет напечатан на output_file, а остальная часть строки будет напечатана на терминале.

./small_script.sh | 
awk -v date=$(date +%s) '{print $0 OFS date > "output_file";print}' 
0 голосов
/ 18 мая 2018

Вы можете использовать команду cut после команды tee:

./small_script.sh | while read R; do echo "$(date +%s) $R"; done | tee output.txt | cut -c12-
0 голосов
/ 18 мая 2018

Вы можете удалить отметку времени, используя sed после команды tee:

./small_script.sh | while read R; do echo "$(date +%s) $R"; done | tee output.txt | sed 's/^[^ ]\+ //'

Регулярное выражение sed соответствует каждому до пробела в начале строки.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...