Ответ на вторую часть -преобразование файлов json в таблицу.
Использование:./json_to_table.sh *.json
#!/bin/bash
for i in "$@"; do
file_content=$(sed -n 's/".*":"\(.*\)",\?/\1/p' "$i" | tr '\n' ' ')
printf "%s %s\n" "$i" "$file_content"
done | column -t
Если вам не нужен красивый формат таблицы, вы можете удалить | column -t
часть (внизу, послеdone
). Тогда поля строки будут разделены одним пробелом, следовательно, каждое будет иметь свою ширину. Он хорош для парсинга программами типа awk
, sed
, но неудобен для чтения человеком.
Примечание:после каждой записи в файле json, кроме последней, должна стоять запятая. Что я имею в виду:
"field8":"310000", <- here
"field9":"si", <-here
"field10":"2017-06-05" <- not here. Last record without comma.
}
Проблема со вторым примером в том, что он вообще не соответствует вашей строке. Он пытается сопоставить ^.\.xyz
, то есть:<beginning of line><any character>.xyz
. Но я подозреваю, что вы пытаетесь сопоставить <some characters>.xyz<end of line>
. Пока для начала вам нужно удалить ^
, а затем вам нужно выяснить, как именно определить <some characters>
для вашей ситуации.
Но вам не нужны два вызова sed, потому что вы можете хранить шаблоны в sed. Если вы окружаете шаблон, который хотите сохранить с (экранированными скобками ), вы можете заменить их позже на\1
(или \2
для второго шаблона и так далее ).
Итак, вы хотите удалить file
, а затем окончательное имя файла в этом:
*xyzfile 0 1 somefilebeingpointedto.xyz
Таким образом, шаблон, который, как я думаю, вы ищете, это (с буквальным текстом «файл» в нем):
<something to keep>file<something to keep><space><pattern without spaces until end of line>
Мы можем сопоставить это с:
^\(.*\)file\(.*\) [^ ]*$
Обратите внимание, что две части, которые мы хотим сохранить, заключены в (экранированные )круглые скобки. Если бы мы не хотели оставлять их на потом, мы могли бы опустить скобки(.*file.* [^ ]*
)
Затем с подстановкой sed вы получите полную строку, которая выглядит как:
sed 's/^\(.*\)file\(.*\) [^ ]*$/\1\2/'
Точка в регулярном выражении sed означает Любой символ , но только один символ.
Таким образом, регулярное выражение ^.\.xyz
означает :С начала строки сопоставьте один символ, затем одну точку, а затем xyz
. Вы можете иметь в виду :^.*\.xyz$
, но это будет соответствовать всей строке (и стереть ее ). Вы должны использовать пробел в качестве разделителя (, предполагая, что имена файлов не содержат пробелов в имени ):[^ ]*\.xyz$
, что означает, что :из пробела(" "
)соответствует нескольким(*
)не -пробелам([^ ]
)символам до расширения .xyz
в конце строки ($
). Вы можете выразить обе замены, если вы перед каждой частью ставите-e
:
sed -e 's/^.*xyzfile/*xyz/' -e 's/ [^ ]*\.xyz$//' myfile.inp
Нет необходимости экранировать *
в правой части замены.
Это можно упростить до:
sed -e 's/xyzfile /*xyz /' -e 's/ [^ ]*\.xyz$//' myfile.inp
Если имя файла может содержать пробелы, регулярное выражение становится более сложным, поскольку нет простого способа выбрать (только )эту часть строки.
Если второе и третье поля имеют только один символ, вы можете использовать скобки захвата и поместить их обратно с помощью\1
:
sed -e 's/xyzfile\(..\).*\.xyz$/xyz\1/' myfile.inp
В расширенный синтаксис регулярных выражений:
sed -E -e 's/xyzfile(..).*\.xyz$/xyz\1/' myfile.inp
Или,если бы поля могли иметь несколько символов (кроме пробела):
sed -E -e 's/xyzfile( [^ ]* [^ ]*).*\.xyz$/xyz\1/' myfile.inp
Это может привести к ошибке, если строка выглядит примерно так: (нетxyzfile
):
*xyzffff 0 1 pointedto.xyz
В этом случае применяйте каждую замену независимо:
sed -E -e 's/xyzfile /xyz /' -e 's/( [^ ]* [^ ]*).*\.xyz$/\1/' myfile.inp