Замена параметра sed многострочной строкой в ​​кавычках

XFS — замечательная файловая система, особенно для больших файлов. Если ваша загрузка включает в себя множество небольших файлов, периодическая очистка любой фрагментации может повысить производительность. Я не беспокоюсь об этом и использую XFS для всех нагрузок. Он хорошо поддерживается, поэтому нет причин не использовать его.

Выделите машину и диск для собственного тестирования различных файловых систем, если вы хотите выяснить, что лучше всего подходит для вашей типичной рабочей нагрузки. Выполнение тестовой загрузки пошагово по всему диску может рассказать вам кое-что о том, как работает тестируемая файловая система.

Единственный способ убедиться в этом — протестировать нагрузку на компьютере.

5
23.12.2020, 11:06
4 ответа

Предположим, что ваш документ JSON выглядит примерно так

{
  "scripts": {
    "other-key": "some value"
  }
}

... и вы хотите вставить другую пару значений ключа -в объект .scripts. Затем вы можете использовать jqдля этого:

$ jq '.scripts.watch |= "tsc -w"' file.json
{
  "scripts": {
    "other-key": "some value",
    "watch": "tsc -w"
  }
}

или,

$ jq '.scripts += { watch: "tsc -w" }' file.json
{
  "scripts": {
    "other-key": "some value",
    "watch": "tsc -w"
  }
}

Оба они заменят уже существующую .scripts.watchзапись.

Обратите внимание, что порядок пар ключей -значений в .scriptsне важен (, так как это не массив ).

Перенаправьте вывод в новый файл, если хотите его сохранить.

Чтобы добавить несколько пар значений ключа -к одному и тому же объекту:

$ jq '.scripts += { watch: "tsc -w", dev: "nodemon dist/index.js" }' file.json
{
  "scripts": {
    "other-key": "some value",
    "watch": "tsc -w",
    "dev": "nodemon dist/index.js"
  }
}

В сочетании с joдля создания JSON, который необходимо добавить к объекту .scripts:

$ jq --argjson new "$( jo watch='tsc -w' dev='nodemon dist/index.js' )" '.scripts += $new' file.json
{
  "scripts": {
    "other-key": "some value",
    "watch": "tsc -w",
    "dev": "nodemon dist/index.js"
  }
}

sedхорош для разбора текста, ориентированного на строку -. JSON не входит в записи с разделителями новой строки -, и sedне знает о правилах цитирования, кодирования символов и т. Д. JSON. Чтобы правильно проанализировать и изменить структурированный набор данных, подобный этому (, или XML, или YAML, или даже CSV при некоторых обстоятельствах ), вы должны использовать правильный синтаксический анализатор.

В качестве дополнительного преимущества использования jqв данном случае вы получаете фрагмент кода, который легко модифицировать в соответствии с вашими потребностями, и который так же легко модифицировать для поддержки изменений в структура входных данных.

8
18.03.2021, 22:41

Кусалананда абсолютно прав, говоря, что специализированный анализатор — правильный инструмент для работы. Однако это можно легко сделать в sed(, по крайней мере, с помощью GNU sed, который также понимает \n). Вы усложняли ситуацию, пытаясь заменить весь шаблон из двух строк -. Вместо этого просто сопоставьте целевую строку и вставьте замену после нее:

"scripts": {

А потом:

$ sed '/"scripts": {/s/$/\n    "watch": "tsc -w",/' file
"scripts": {
    "watch": "tsc -w",

Это означает, что «если эта строка соответствует строке "scripts": {, то замените конец строки новой строкой (\n), за которой следует "watch": "tsc -w",. Кроме того, вы можете использовать команду ased для добавления текста:

$ sed '/"scripts": {/a\    "watch": "tsc -w",' file 
"scripts": {
    "watch": "tsc -w",
6
18.03.2021, 22:41

Хотя я согласен с тем, что jqявляется оптимальным инструментом для использования, эту конкретную задачу можно легко выполнить с помощью sed. По сути, задача состоит в том, чтобы добавить строку текста после совпадения шаблона в предыдущей строке.

$ cat example.json
{
   "scripts": {  
      "access_token": "asadasd",
      "expires_in": "3600"
   }
}

$ cat demo.sh
#!/bin/bash

SRC='"scripts": {'
DST='\ \ \ \ \ \ "watch": "tsc -w",'

sed '/'"$SRC"'/a '"$DST"'' example.json

$./demo.sh
{
   "scripts": {  
      "watch": "tsc -w",
      "access_token": "asadasd",
      "expires_in": "3600"
   }
}
$
0
18.03.2021, 22:41

Так как sedрассматривает весь текст как regex, поэтому мы должны экранировать строки, прежде чем вставлять их в код sed. Кроме того, нам нужно позаботиться о том, находится ли входящая строка слева или справа от команды s///, потому что список символов BRE различен с обеих сторон.

s='[[:blank:]]'
srch_str='"scripts": {'
repl_str='"watch": "tsc -w",'

esc_srch_str=$(
  printf '%s\n' "$srch_str" |
  sed -e 's:[][\/.^$*]:\\&:g'
)

esc_repl_str=$(
  printf '%s\n' "$repl_str" |
  sed -e 's:[\/&]:\\&:g'
)

sed -e "
  /^$s*$esc_srch_str\$/G
  s/^\($s*\).*\n/&\1  $esc_repl_str/
" file

Выход:

{
  "scripts": {
    "watch": "tsc -w",
    "other-key": "some value"
  }
}
0
18.03.2021, 22:41

Теги

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