Как перебирать файлы, имена которых содержат вертикальные линии и пробелы в bash

Вы можете попробовать это sed следующим образом:

В приведенном ниже коде используется версия sed GNU (хотя она также может быть перенесена на POSIX-совместимый формат)

sed -e '
   /[{]/,/[}]/!b
   /"tags":/!b

   h;s/"tags":/&\n/;s/\n.*/ /;s/./ /g;x

   s/"tags":/&\n/
   :a
   s/\(\n.*\)\([^"]\) \([^"]\)/\1\2","\3/;ta

   y/\n/[/;s/$/]/;G

   :b
   s/","\(.*\)\(\n.*\)/",\2"\1\2/;tb
   s/\(.*\)\n.*/\1/

' yourjsonfile

Работает

  1. Мы выбираем диапазон от { до следующих } строк.
  2. Увеличьте масштаб строки "tags" в выбранном диапазоне.
  3. Вычислите вложенные пространства для данного тега и сохраните его в удержании.
  4. Двойные кавычки данных тега в цикле :a
  5. Вставка вложенных пробелов после , в цикле :b
  6. Удалить все после последней новой строки в пространство шаблона и печать.

Результаты

[
 {
   "title": "Some Title",
   "tags":["tagA",
           "tag-B",
           "tagC"]
 },
 {
   "title": "Some Title 2",
   "tags":["tagA",
           "tagC"]
 },
 ...
]
0
27.08.2017, 13:32
2 ответа
find. -name '*.html' -print0 | while IFS= read -r -d ''; do

В этой строке нет ничего, что могло бы вызвать какие-либо проблемы с именами файлов, содержащими комбинации пробелов и/или каналов в именах:

bash-4.4$ touch 'A|B' '1|2' 'quux|foo bar'
bash-4.4$ ls
1|2          A|B          quux|foo bar
bash-4.4$ find. -print0 | while IFS= read -r -d ''; do printf '"%s"\n' "$REPLY"; done
"."
"./A|B"
"./1|2"
"./quux|foo bar"

Заметьте также, что в зависимости от того, что вы хотите сделать с найденными именами, почти всегда лучше делать это с -execизнутри самого find:

find. -type f -name "A*" -exec cat {} \;

Связанный ответ на другой вопрос:Почему мой сценарий оболочки забивается пробелами или другими специальными символами?(см., в частности, "Как обработать файлы, найденные с помощью find?" в этом ответе ).

3
28.01.2020, 02:24

Такой простой вызов findнужен только для очень старых версийbash(до -4.0 ). Использование оператора globstarнамного проще:

shopt -s globstar
for f in **/*.html; do
   ...
done
0
28.01.2020, 02:24

Теги

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