Если у вас есть perl переименование Ларри Уолла
rename 's/[.]jpeg[0-9]*/.jpeg/' *.jpeg[0-9]*
если у вас есть только переименование Util -Linux, это не сработает.
Вы можете использовать цикл for в bash
for n in *.jpeg[0-9]*
do mv -i "$n" "${n%%.jpeg[0-9]*}.jpeg"
done
${var%%pattern}
представляет собой расширение стандартного параметра , которое расширяется до значения var
с удалением (самой длинной )замыкающей части, соответствующей pattern
. Итак, если n
— это foo.jpeg123
, ${n%%.jpeg[0-9*}
— это foo
.(foo.jpeg1abc
также приведет к foo
.)
Чтобы изменить одну запись, убедитесь, что вы используете |=
и что левая часть этого оператора обновления является путем в исходном документе:
jq --arg name John --arg phone 4321 \
'(.contacts[] | select(.name == $name) ).phone |= $phone' file
Вы не можете использовать .contacts[] | select(.name == "John") |.phone |=...
, так как select()
фактически извлекает набор элементов из массива contacts
. Поэтому вы будете изменять только те элементы, которые вы извлекаете, отдельно от основной части документа.
Обратите внимание на разницу в
(... | select(...) ).phone |=...
^^^^^^^^^^^^^^^^^^^^^
path in original document
который работает, и
... | select(...) |.phone |=...
^^^^^^^^^^^
extracted bits
что не работает.
Использование цикла для более чем одной записи, предполагая, например, что.bash
:
names=( John Jane )
phones=( 4321 4321 )
tmpfile=$(mktemp)
for i in "${!names[@]}"; do
name=${names[i]}
phone=${phones[i]}
jq --arg name "$name" --arg phone "$phone" \
'(.contacts[] | select(.name == $name) ).phone |= $phone' file >"$tmpfile"
mv -- "$tmpfile" file
done
То есть я помещаю имена в один массив, а новые числа — в другой, затем циклически перебираю индексы и обновляю file
каждую запись, которую нужно изменить, используя временный файл в качестве промежуточного хранилища.
Или, с ассоциативным массивом:
declare -A lookup
lookup=( [John]=4321 [Jane]=4321 )
for name in "${!lookup[@]}"; do
phone=${lookup[$name]}
# jq as above
done
Предположим, что у вас есть входной документ JSON с новыми телефонными номерами, например
{
"John": 1234,
"Jane": 5678
}
, который можно создать с помощью
jo John=1234 Jane=5678
Затем вы можете обновить номера в одном jq
вызове:
jo John=1234 Jane=5678 |
jq --slurpfile new /dev/stdin \
'.contacts |= map(.phone = ($new[][.name] //.phone))' file
Это читает наш ввод JSON с новыми числами в структуре, $new
,это похоже на
[
{
"John": 1234,
"Jane": 5678
}
]
Используется при вызове map()
для изменения телефонных номеров любого контакта в списке. //.phone
гарантирует, что если имя не указано в списке, номер телефона останется прежним.
Основываясь на ответе Кусалананды, если вы хотите найти и заменить только 2 значения, вы можете сделать что-то подобное за один вызов jq:
jq '(.contacts[] | select(.name == "John") ).phone |= "4321" |
(.contacts[] | select(.name == "Jane") ).phone |= "8765"' \
contacts.json
Или, таким образом, цепочка из 2 вызовов jq:
cat contacts.json | \
jq '(.contacts[] | select(.name == "John") ).phone |= "4321"' | \
jq '(.contacts[] | select(.name == "Jane") ).phone |= "8765"'