Что касается вопроса, поднятого в некоторых других ответах, вы можете использовать утилиту mv
, чтобы предложить социальный барьер:
mv yourfile THIS_IS_user38537_FILE_PLEASE_DO_NOT_REMOVE
Используйте цикл для обработки файлов один за другим.
Например, сwhile read
:
find. -name '*.json' | while read fname; do
newname=$(jq -r '.billingAccountList[0]' "${fname}").json
mv "${fname}" "${newname}"
done
Использование for
возможно, но оно более чувствительно к пробелам в именах файлов:
for fname in $(find. -name '*.json'); do
... (same as above)...
Также обратите внимание, что вы перемещаете файлы в текущий каталог, поскольку исходный путь удаляется, поэтому, если вы хотите сохранить структуру каталогов:
find. -name '*.json' | while read fname; do
fdir=$(dirname "${fname}")
newname=$(jq -r '.billingAccountList[0]' "${fname}").json
mv "${fname}" "${fdir}/${newname}"
done
ОБНОВЛЕНИЕ:Использование jq -r
, предложенное @steeldriver. Спасибо!
Вы должны иметь возможность использовать jq -r
для вывода необработанных (строк без кавычек )-вместо удаления кавычек с помощьюtr
Также я предполагаю, что вы хотите переименовать файлы относительно их родительского каталога (, поэтому, например, если значение .billingAccountList[0]
в path/to/file.json
равно foo
, тогда новое имя должно быть path/to/foo.json
, а не foo.json
), и что ваша реализация find
имеет-execdir
Так что я бы сделал что-то вроде
find. -name '*.json' -execdir sh -c '
echo mv -- "$1" "$(jq -r ".billingAccountList[0]" < "$1").json"
' find-sh {} \;
или (хотя бы с GNUfind
)более эффективно
find. -name '*.json' -execdir sh -c '
for f; do echo mv "$f" "$(jq -r ".billingAccountList[0]" < "$f").json"; done
' find-sh {} +
Удалите echo
, как только убедитесь, что он работает правильно.
С zsh
иzmv
(для лучшего разрешения конфликтов):
autoload zmv
zmv -n '(**/)*.json(#qD.)' '$1$(jq -r '.billingAccountList[0]' < $f).json
(удалить -n
когда счастлив ).