У меня есть фрагмент кода, который я использую для анализа файла журнала и вывода необходимой мне информации.
for i in $(cat ~/jlog/"$2"); do
grep "$1" ~/jlog/"$2" |
awk '/\([a-zA-Z0-9.]+/ {print $7}'
done;
Проблема в том, что когда я ввожу данные, ответ отображается несколько раз:
(1.3.51.0.1.1.10.10.30.48.2084865.2084839/1.2.840.113619.2.284.3.17454802.933.1401109176.280.1)
(1.3.51.0.1.1.10.10.30.48.2084865.2084839/1.2.840.113619.2.284.3.17454802.933.1401109176.283.1)
(1.3.51.0.1.1.10.10.30.48.2084865.2084839/1.2.840.113619.2.80.977011700.14346.1401109696.2)
(1.3.51.0.1.1.10.10.30.48.2084865.2084839/1.2.840.113619.2.80.977011700.14346.1401109706.51)
(1.3.51.0.1.1.10.10.30.48.2084865.2084839/1.2.840.113619.2.80.977011700.14346.1401109758.100)
(1.3.51.0.1.1.10.10.30.48.2084865.2084839/1.2.840.113619.2.80.977011700.14346.1401109773.149)
(1.3.51.0.1.1.10.10.30.48.2084865.2084839/1.2.840.113619.2.80.977011700.14346.1401109810.198)
(1.3.51.0.1.1.10.10.30.48.2084865.2084839/1.2.840.113619.2.80.977011700.14346.1401109818.247)
Есть ли способ обрезать это так, чтобы отображать только первую серию данных один раз. Мне нужно 1.3.51.0.1.1.10.10.30.48.2084865.2084839
распечатать только один раз.
Я пробовал изменить это так, но Bash это не нравится:
for i in $(cat ~/jlog/"$2"); do
grep "$1" ~/jlog/"$2" |
awk '/\([a-zA-Z0-9.]+/' |
awk -F'[(/]' ' {print $2, exit}'
done;
Затем попробовал это:
for i in $(cat ~/jlog/"$2"); do
grep "$1" ~/jlog/"$2" |
awk -F'[(/]' '/\([a-zA-Z0-9.]+/ {print $2, exit }'
done;
решение1
Попробуй это,
for i in $(cat ~/jlog/"$2"); do
grep "$1" ~/jlog/"$2" |
awk '/\([a-zA-Z0-9.]+/ {print $7; exit}'
done;
exit
в команде awk происходит выход после вывода первого совпадения.
ИЛИ
Просто передайте вывод for
команды в следующую команду awk:
for .... | awk -F'[(/]' '{print $2;exit}'
решение2
Вам не нужен for
цикл — один вызов grep
выведет все соответствующие строки из файла, так что вы просто повторяете одну и ту же операцию снова и снова столько раз, сколько строк в файле.
Технически вам не нужны оба awk
и grep
ни один из них, поскольку оба могут выполнять текстовое сопоставление. Если вы хотите получить более конкретный ответ, то опубликуйте выдержку из файла журнала и пример того, какой вывод вы хотите получить.
решение3
Вы не объяснили, что вы на самом деле делаете, поэтому я сделаю несколько предположений. Я предполагаю, что вы запускаете скрипт с именем foo.sh
и передаете ему строку и имя файла в качестве аргумента. Затем они становятся $1
и $2
соответственно. Предположительно, вы запускаете его с чем-то похожим на
foo.sh SearchPattern LogFileName
В любом случае, for
цикл i) совершенно бесполезен, так как вы не используете i
переменную, созданную циклом for i in ...
. ii) очень неправильный, так как это заставит i
принимать значение каждогословоа не вся строка, о которой вы, вероятно, думали iii) причина всех ваших проблем. Вы получаете одни и те же результаты несколько раз, потому что вы запускаете одну и ту же команду несколько раз. Вы получите один результат для каждой строки вашего файла.
В любом случае, то, что вы хотите, можно сделать с помощью чего-то столь простого, как
grep "$1" ~/jlog/"$2" | awk '/\([a-zA-Z0-9.]+/ {print $7}'
Или проще:
awk '/'"$1"'/\([a-zA-Z0-9.]+/ {print $7}' ~/jlog/"$2"
Обратите awk
внимание, что "$1"
не находится в одинарных кавычках. Это заставляет bash расширить его до того, что в данный момент хранится в , $1
прежде чем он будет передан в awk
.