Одной из возможностей, которая не требует разветвления, является использование 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
Удалите 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"
К сожалению, у меня недостаточно репутации, чтобы оставлять комментарии, но в дополнение к ответу Эда Мортона :если вы вызываете 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
Если вы не можете установить 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
Если вы хотите попробовать это без 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
Некоторые идеи:
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
что, как вы видите, избавляет от множества отвлекающих факторов:-)
Вы можете извлечь подстроку, используя встроенные функции bash, в частности, используя только замену параметров:
v=$(gps location)
v1=${v#*\"longitude\":\ \"}
echo "${v1%%\"*}"
При этом мы удаляем все до longitude": "
в переменной v, начиная слева.Затем на следующем шаге мы удаляем все до последнего, начиная справа. Остаются продольные координаты.
Выполнено с помощью приведенной ниже команды 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"