Мне нужно провести различие между сценариями первого изображения и второго изображения при получении информации с помощью grep. Оба они созданы, но один для изображения, а один для твита. Все те, для твитов, имеют }, в строке выше, поэтому я думал, что могу использовать эту информацию, но я не уверен, как это сделать.
Вот grep, который я использую:
grep -wirnE 'Wed Oct 19 2(1:[0-5][0-9]:[0-5][0-9]|2:([0-2][0-9]:[0-5][0-9]|30:00)) .* 2016' *
Вы можете использовать опции -A1 и -B1, чтобы grep напечатал строку после (-A) и до (-B) соответствующей строки. Попробуйте следующую командную строку:
grep -B1 created_at log-file|grep -A1 '^}'|grep created_at
Я протестировал со следующим входным файлом с именем log-file
asdf
qwerty
...
},
"created_at" "date-with-near-}"
zxcv
some other string
"created_at" "date-without-}"
...
Последовательность тестирования
$ grep -B1 created_at log-file
},
"created_at" "date-with-near-}"
--
some other string
"created_at" "date-without-}"
$ grep -B1 created_at log-file|grep -A1 '^}'
},
"created_at" "date-with-near-}"
$ grep -B1 created_at log-file|grep -A1 '^}'|grep created_at
"created_at" "date-with-near-}"
Вы можете использовать команду sed N для чтения нескольких строк в пространстве шаблонов.
Чтобы найти первый:
sed -nr '/\}/N; /.*\}.*\n.*"Wed Oct 19 .* 2016/Ip' file
и удалить предыдущая строка:
sed -nr '/}/N; s/.*}.*\n(.*"Wed Oct 19 .* 2016)/\1/Ip' file
Проблема в том, что sed не укажет вам, из какого файла находится строка, и у него нет рекурсивного флага поиска файла (afaik). Это можно обойти, включив рекурсивное подталкивание с помощью ** в оболочке (но проблема «какой файл сделал это?»):
shopt -s globstar
sed -nrs '/}/N; s/.*}.*\n(.*"Wed Oct 19 .* 2016)/\1/Ip' **
С несколькими файлами добавьте -s, чтобы sed рассматривали поток как отдельные файлы (чтобы избежать нежелательных многострочных совпадений). Вы можете добавить свое подробное выражение в середине ...
sed -nrs '/}/N; s/.*}.*\n(.*"Wed Oct 19 2(1:[0-5][0-9]:[0-5][0-9]|2:([0-2][0-9]:[0-5][0-9]|30:00)) .* 2016)/\1/Ip' **
Для второго появления с нет } в предыдущей строке
sed -nr '/^[^}]*$/N; /.*\n.*"Wed Oct 19 .* 2016/Ip' file
и удалите предыдущую строку:
sed -nr '/^[^}]*$/N; s/.*\n(.*"Wed Oct 19 .* 2016)/\1/Ip' file
for f in **; do [[ -f "$f" ]] && echo -e ""$f":\n tweet: $(sed -nr '/}/N; s/.*}.*\n(.*"Wed Oct 19 .* 2016)/\1/Ip' "$f")\n image: $(sed -nr '/^[^}]*$/N; s/.*\n(.*"Wed Oct 19 .* 2016)/\1/Ip' "$f")"; done
или ... чуть более читаемо (!)
#!/bin/bash
shopt -s globstar
for f in **; do
[[ -f "$f" ]] &&
echo -e ""$f":\n tweet: $(sed -nr '/}/N; s/.*}.*\n(.*"Wed Oct 19 .* 2016)/\1/Ip' "$f")"
done
Это дает вывод, похожий на:
file1:
tweet: "created_at": "Wed Oct 19 12:36:54 +0000 2016"
image: "created_at": "Wed Oct 19 somethingsomething 2016"
file2:
tweet: "created_at": "Wed Oct 19 random-chars 2016"
image: "created_at": "Wed Oct 19 whatever 2016"
Если вы хотите исключить тот или иной, удалите соответствующая часть из сценария, например, для получения только твита ...
for f in **; do
[[ -f "$f" ]] &&
echo -e ""$f":\n tweet: $(sed -nr '/}/N; s/.*}.*\n(.*"Wed Oct 19 .* 2016)/\1/Ip' "$f")"
done
Вы можете использовать опции -A1 и -B1, чтобы grep напечатал строку после (-A) и до (-B) соответствующей строки. Попробуйте следующую командную строку:
grep -B1 created_at log-file|grep -A1 '^}'|grep created_at
Я протестировал со следующим входным файлом с именем log-file
asdf
qwerty
...
},
"created_at" "date-with-near-}"
zxcv
some other string
"created_at" "date-without-}"
...
Последовательность тестирования
$ grep -B1 created_at log-file
},
"created_at" "date-with-near-}"
--
some other string
"created_at" "date-without-}"
$ grep -B1 created_at log-file|grep -A1 '^}'
},
"created_at" "date-with-near-}"
$ grep -B1 created_at log-file|grep -A1 '^}'|grep created_at
"created_at" "date-with-near-}"
Вы можете использовать команду sed N для чтения нескольких строк в пространстве шаблонов.
Чтобы найти первый:
sed -nr '/\}/N; /.*\}.*\n.*"Wed Oct 19 .* 2016/Ip' file
и удалить предыдущая строка:
sed -nr '/}/N; s/.*}.*\n(.*"Wed Oct 19 .* 2016)/\1/Ip' file
Проблема в том, что sed не укажет вам, из какого файла находится строка, и у него нет рекурсивного флага поиска файла (afaik). Это можно обойти, включив рекурсивное подталкивание с помощью ** в оболочке (но проблема «какой файл сделал это?»):
shopt -s globstar
sed -nrs '/}/N; s/.*}.*\n(.*"Wed Oct 19 .* 2016)/\1/Ip' **
С несколькими файлами добавьте -s, чтобы sed рассматривали поток как отдельные файлы (чтобы избежать нежелательных многострочных совпадений). Вы можете добавить свое подробное выражение в середине ...
sed -nrs '/}/N; s/.*}.*\n(.*"Wed Oct 19 2(1:[0-5][0-9]:[0-5][0-9]|2:([0-2][0-9]:[0-5][0-9]|30:00)) .* 2016)/\1/Ip' **
Для второго появления с нет } в предыдущей строке
sed -nr '/^[^}]*$/N; /.*\n.*"Wed Oct 19 .* 2016/Ip' file
и удалите предыдущую строку:
sed -nr '/^[^}]*$/N; s/.*\n(.*"Wed Oct 19 .* 2016)/\1/Ip' file
for f in **; do [[ -f "$f" ]] && echo -e ""$f":\n tweet: $(sed -nr '/}/N; s/.*}.*\n(.*"Wed Oct 19 .* 2016)/\1/Ip' "$f")\n image: $(sed -nr '/^[^}]*$/N; s/.*\n(.*"Wed Oct 19 .* 2016)/\1/Ip' "$f")"; done
или ... чуть более читаемо (!)
#!/bin/bash
shopt -s globstar
for f in **; do
[[ -f "$f" ]] &&
echo -e ""$f":\n tweet: $(sed -nr '/}/N; s/.*}.*\n(.*"Wed Oct 19 .* 2016)/\1/Ip' "$f")"
done
Это дает вывод, похожий на:
file1:
tweet: "created_at": "Wed Oct 19 12:36:54 +0000 2016"
image: "created_at": "Wed Oct 19 somethingsomething 2016"
file2:
tweet: "created_at": "Wed Oct 19 random-chars 2016"
image: "created_at": "Wed Oct 19 whatever 2016"
Если вы хотите исключить тот или иной, удалите соответствующая часть из сценария, например, для получения только твита ...
for f in **; do
[[ -f "$f" ]] &&
echo -e ""$f":\n tweet: $(sed -nr '/}/N; s/.*}.*\n(.*"Wed Oct 19 .* 2016)/\1/Ip' "$f")"
done