Котировки не обрабатываются при выводе расширений. Если вы сделаете $(echo '"foo bar"')
или $(echo "\"foo bar\"")
, аргументом основной команды станет "foo
и bar"
. С буквальными кавычками и как два отдельных аргумента из-за разделения слов .
По умолчанию разбиение слов происходит на любых пробелах, пробелах или новых строках, поэтому из вывода find
вы не можете отличить, какие пробелы являются частью имени файла, а какие частью того, что find
печатает. чтобы разделить их. Даже в общем случае их нельзя отличить друг от друга, так как имена файлов также могут содержать символы новой строки...
Что вы можете сделать, так это:
find... -print0 | xargs -0 vlc
или
find... -exec vlc {} +
Первый выводит find
имена файлов, разделенные нулевыми байтами, и указывает xargs
ожидать именно этого. Однако не все системы имеют find -print0
и xargs -0
.
Второй имеет find
запуск самого себя vlc
, завершающий {} +
сообщает ему передать несколько имен файлов для одного вызова vlc
.
Если нужно найти очень большое количество файлов, и они не помещаются в одну командную строку, то оба они могут запустить vlc
более одного раза.
См.:
Использование echo
для отладки этого на самом деле не работает, так как он будет объединять свои аргументы с одним пробелом, делая невозможным определение разницы между echo foo bar
и echo "foo bar"
.
Предполагая, что поля всегда находятся в заданном порядке, что в первой строке ввода есть строка заголовка, а поля разделяются несколькими символами пробела, вы можете сжать ряды последовательных пробелов с помощью tr
и проанализировать строку. данные с jq
.
database-client-command |
tr -s ' ' |
jq -c -Rn '
input | split(" ") as $head |
inputs | split(" ") |
to_entries |
map(.key = $head[.key]) |
[.[:2][], { key: "DATA", value: (.[2:] | from_entries) } ] |
from_entries'
Выражение jq
считывает исходные данные из tr
как отдельные строки.
Первая строка разбивается на заголовки и сохраняется в виде массива в $head
.
Мы разделяем оставшиеся строки на массивы так же, как и с заголовком. Фильтр to_entries
преобразует каждый массив в «входную форму» (наборы объектов с ключами key
и value
), а фильтр map()
заменяет числовые индексы массива заголовками из $head
как ключи.
После map()
фильтр переупорядочивает массив, третий элемент которого перемещается вниз в отдельный DATA
подобъект -и преобразуется обратно из «формы ввода».
По завершении перестановки ключей и данных фильтр from_entries
возвращает массив из «формы ввода».
На выходе сценария будет набор объектов JSON, и, учитывая данные в вашем вопросе, они будут выглядеть следующим образом.
{"CID":"12","CN":"2123","DATA":{"XY":"120.9","NAT":"29.0","UIC":"100.0","DATE":"2018-06-08","Region":"JAIPUR"}}
{"CID":"13","CN":"0987","DATA":{"XY":"78.9","NAT":"100.3","UIC":"28.8","DATE":"2020-12-09","Region":"DELHI"}}
Если вы хотите изменить Region
на REGION
и DATE
на Date
, рассмотрите возможность сделать это при запросе к базе данных или на этапе постобработки -.
Обратите внимание, что ожидаемый результат не является допустимым JSON из-за запятой в конце первой строки.
Предполагая, что вы ДЕЙСТВИТЕЛЬНО не хотите преобразовывать DATE
в Date
и Region
в REGION
(, если вы это сделаете, это будет легко настроить после того, как вы объясните логику выбора тегов для изменения )и что вам действительно нужен ,
в конце каждой строки вывода, кроме последней (снова, простая настройка, если вы этого не сделаете ), затем используйте любой awk в любой оболочке на каждом компьютере Unix:
$ cat tst.awk
NR==1 {
split($0,tags)
next
}
{
printf "%s{%s,%s,\"DATA\":{", sep, fmt(1), fmt(2)
for (i=3; i<=NF; i++) {
printf "%s%s", fmt(i), (i<NF ? "," : "}}")
}
sep = ",\n"
}
END {
print ""
}
function fmt(fldNr, tag, val) {
tag = tags[fldNr]
val = $fldNr
gsub(/"/,"\\\"",val)
return sprintf("\"%s\":\"%s\"", tag, val)
}
$ awk -f tst.awk file
{"CID":"12","CN":"2123","DATA":{"XY":"120.9","NAT":"29.0","UIC":"100.0","DATE":"2018-06-08","Region":"JAIPUR"}},
{"CID":"13","CN":"0987","DATA":{"XY":"78.9","NAT":"100.3","UIC":"28.8","DATE":"2020-12-09","Region":"DELHI"}}