На тот случай, если rsync-решение Дэвида Кингса не работает для вас или вы действительно хотите сделать это в bash (зачем вообще), вот как вы могли сделай это:
#!/bin/bash
your_command_to_execute &
myPid=$!
sleepTime=5
while kill -0 "$myPid" 2> /dev/null
do
# Sleep for the defined time
sleep $sleepTime
# And print the time since the script started in seconds
echo -en "Runtime $SECONDS\033[0K\r"
done
Возможно, вы захотите использовать что-нибудь, чтобы немного лучше отформатировать время.
Также в настоящее время сценарий печатает секунды с момента запуска сценария, а не с момента начала операции cp (если вы хотите изменить это простое, вычтите секунды до цикла из текущего $ SECONDS
)
Для использования jq
на основе функции walk
(требуется последняя версия):
jq 'walk(.name?="XXX")' file
Если ваш jq
не поддерживает функцию walk
, просто определите ее как:
jq '
# Apply f to composite entities recursively, and to atoms
def walk(f):
. as $in
| if type == "object" then
reduce keys[] as $key
( {};. + { ($key): ($in[$key] | walk(f)) } ) | f
elif type == "array" then map( walk(f) ) | f
else f
end;
walk(.name?="XXX")
' file
Операции присваивания jq могут выполнять обновление одновременно в любом количестве местоположений, которое вы можете назвать, и предназначены для такого рода ситуаций. Вы можете использовать
jq '(.. |.name?) |= "XXXX"'
От до найдите каждое поле с именем «имя» в любом месте и замените значение в каждом сразу на «XXXX» и выведите результирующий объект.
Это всего лишь ..|.a?
пример из рекурсивного -документа спуска в сочетании с присваиванием обновления .
Он использует оператор рекурсивного спуска..
для поиска каждого отдельного значения в дереве, затем извлекает поле «имя» из каждого из них с помощью .name
, подавляет любые ошибки из не -совпадающих значений с ?
, а затем обновляет объект во всех этих местах сразу с помощью «XXXX», используя оператор присваивания update -|=
, и выводит новый объект.
Это будет работать независимо от файловой структуры и обновлять каждое поле имени везде.
В качестве альтернативы, если файл всегда имеет эту структуру, и вы хотите изменить те конкретные поля «имя», , а не просто любое старое имя, вы также можете просто перечислить их и назначить им как группа тоже:
jq '(.name,.contact[].name,.group[].name) |= "XXXX"'
Выполняет такое же назначение для
все сразу. Это особенно полезно, если в файле могут быть другие поля имен где-то не связанные, которые вы не хотите изменять. Он находит только три набора названных там местоположений и обновляет их все одновременно.
Если значение является просто литералом, как здесь, тогда простое присваивание с=
также работает и экономит вам символ:(..|.name?)="XXXX"
-вам также понадобится это, если ваше значение вычисляется на основе всей вершины -объект уровня. Если вместо этого вы хотите вычислить новое имя на основе старого, вам нужно использовать |=
. Если я не уверен, что использовать, |=
обычно ведет себя немного лучше в крайних случаях.
Если вам нужно выполнить несколько замен , вы можете связать их вместе:
jq '(..|.name?) = "XXXX" | (..|.lname?) = "1234"'
будет везде обновлять поля «имя» и «lname» и выводить весь обновленный объект один раз.
Несколько других подходов, которые могут работать:
Вы также можете четко указать, что вы выбираете с помощью
(..|objects|select(has("name"))).name |= "XXXX"`
, который находит все, затем только объекты, затем только объекты, у которых есть «имя», затем поле имени этих объектов и выполняет то же обновление, что и раньше.
Если вы используете разрабатываемую версию jq (маловероятно ), тогда функцияwalk
также может выполнять эту работу:walk(.name?="XXXX")
. Все остальные версии будут работать с последней выпущенной версией 1.5.
Альтернативное множественное обновление -может быть
jq '(..|select(has("name"))?) += {name: "XXXX", lname: "1234"}'
который находит все с именем, а затем устанавливает как «имя», так и «lname» для каждого объекта, используя арифметическое обновление -присваивание*=
и поведение слияния, которое +
имеет для объектов .