Разбор строки по ключевым словам

Одной из возможностей, которая не требует разветвления, является использование socatподробного вывода, а не данных. Моя версия socat -vвключает длину данных в подробный вывод, так что вы знаете, где она заканчивается. Например,

mkfifo mypipe
while sleep 3
do    printf "%sNONEWLINE" $RANDOM
done |
socat -u - UDP4:localhost:9999  &
socat -u -v UDP-RECV:9999 - >/dev/null 2>mypipe  &
cat -uv mypipe

будет выводить перед каждым элементом данных (, например,9430NONEWLINE)заголовок, начинающийся >с датой и длиной.

> 2018/07/28 10:29:33.965222  length=13 from=0 to=12
9430NONEWLINE> 2018/07/28 10:29:36.968335  length=14 from=13 to=26
26947NONEWLINE> 2018/07/28 10:29:39.971025  length=14 from=27 to=40
15126NONEWLINE
5
17.07.2020, 00:26
7 ответов

Удалите Location:и у вас останется JSON:

$ echo '{"date": "16/07/20", "time": "19:01:22", "latitude": "34.321", "longitude": "133.453", "altitude": "30m"}' |
    jq.longitude
"133.453"

См. на справочной странице, есть ли у gpsвозможность не печатать ключевое слово Location:впереди, если это не сделать, это легко, например.:

$ echo 'Location: {"date": "16/07/20", "time": "19:01:22", "latitude": "34.321", "longitude": "133.453", "altitude": "30m"}' |
    cut -d':' -f2- | jq.longitude
"133.453"

или:

$ echo 'Location: {"date": "16/07/20", "time": "19:01:22", "latitude": "34.321", "longitude": "133.453", "altitude": "30m"}' |
    sed 's/Location://' | jq.longitude
"133.453"
12
18.03.2021, 23:19

К сожалению, у меня недостаточно репутации, чтобы оставлять комментарии, но в дополнение к ответу Эда Мортона :если вы вызываете jqс параметром -r, он автоматически удаляет кавычки, когда вывод представляет собой просто строку. (как в вашем случае):

$ echo 'Location: {"date": "16/07/20", "time": "19:01:22", "latitude": "34.321", "longitude": "133.453", "altitude": "30m"}' | cut -d':' -f2- | jq -r.longitude
133.453
5
18.03.2021, 23:19

Если вы не можете установить jq, вы можете сделать это в чистом bash, используя зацикливание.

i=1
words=$(gps location)
word=$(echo $words | cut -d',' -f$i)
while ( [ -n "$word" ] )
  do
  echo $word | grep longitude | cut -d' ' -f2
  (( i+=1 ))
  word=$(echo $words | cut -d',' -f$i)
done
0
18.03.2021, 23:19

Если вы хотите попробовать это без jq(, например. поскольку он недоступен ), и , вывод всегда представляет собой один -лайнер, как следует из вашего примера, следующий подход sedтакже будет работать:

sed -r 's/.*"longitude": "([^"]+)".*/\1/'

Это будет

  • искать строку, заключенную в двойные -кавычки ("([^"]+)", т. е. начиная с ", за которой следует строка, содержащая «что угодно, кроме "» до закрытия "), где заключенное содержимое определяется как « группа захвата" (... ), которая находится сразу после строки"longitude":
  • и замените в основном всю строку содержимым группы захвата(\1)-в вашем случае,фактическое значение долготы

Тест:

~$ echo 'Location: {"date": "16/07/20", "time": "19:01:22", "latitude": "34.321", "longitude": "133.453", "altitude": "30m"}' | sed -r 's/.*"longitude": "([^"]+)".*/\1/'
133.453
2
18.03.2021, 23:19

Некоторые идеи:

grep -o longitude.:.* < in | grep -o '[0-9.]*' | head -1

grep -o longitude.:.* < in | cut -f3 -d'"'

Люди часто забывают скромныхtr:

grep -o longitude.:.* < in | tr -dc 0-9., | cut -f1 -d,

или даже лучше:

tr -dc ' La-z0-9.' < in | grep -o longitude.[0-9.]* | cut -f2 -d' '

Последнее будет иметь больше смысла, если вы поймете, что первый шаг производит

Location date 160720 time 190122 latitude 34.321 longitude 133.453 altitude 30m

что, как вы видите, избавляет от множества отвлекающих факторов:-)

0
18.03.2021, 23:19

Вы можете извлечь подстроку, используя встроенные функции bash, в частности, используя только замену параметров:

v=$(gps location)
v1=${v#*\"longitude\":\ \"}
echo "${v1%%\"*}"

При этом мы удаляем все до longitude": "в переменной v, начиная слева.Затем на следующем шаге мы удаляем все до последнего, начиная справа. Остаются продольные координаты.

1
18.03.2021, 23:19

Выполнено с помощью приведенной ниже команды awk, все работает нормально

имя файла кота

Location: {"date": "16/07/20", "time": "19:01:22", "latitude": "34.321", "longitude": "133.453", "altitude": "30m"}

команда

awk '{for(i=1;i<=NF;i++){if($i ~ /latitude/){print $(i+1)}}}' filename

выход

"34.321"

Питон

#!/usr/bin/python
a="""Location: {"date": "16/07/20", "time": "19:01:22", "latitude": "34.321", "longitude": "133.453", "altitude": "30m"}"""

b=a.split(":")
for i in range(0,len(b),1):
    if "longitude" in b[i]:
        print b[i+1].split(",")[0]

выход

 "133.453"
0
18.03.2021, 23:19

Теги

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