Печатать только первый матч один раз

У меня есть фрагмент кода, который я использую для анализа файла журнала и печати необходимой информации.

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;
3
задан 25 June 2014 в 21:14

3 ответа

Попробуйте это,

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}'
5
ответ дан 25 June 2014 в 21:14

Вам не нужно for цикл - единственный вызов grep произведет все согласующие отрезки длинной линии из файла, таким образом, Вы просто повторите ту же операцию много раз для так же много раз, как существуют строки в файле.

Технически, Вам не нужно и awk и grep ни один, так как оба могут сделать текстовое соответствие. Если Вы хотите более определенный ответ, тогда отправляют извлечение файла журнала и пример того, что производит Вас, хотят.

2
ответ дан 25 June 2014 в 21:14

Вы не объяснили, что Вы на самом деле делаете так, я сделаю несколько предположений. Я предполагаю, что Вы запускаете названный скрипт 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" не в одинарных кавычках. Это заставляет удар развернуть его до того, что в настоящее время сдерживается $1 прежде чем это будет передано awk.

1
ответ дан 25 June 2014 в 21:14

Другие вопросы по тегам:

Похожие вопросы: