Renomeia um grupo de arquivos para uma string que existe dentro de cada um

1

Eu tenho um grupo de arquivos json. Cada arquivo contém um objeto json e todos eles têm o mesmo esquema. Existe um campo no json que eu quero renomear o arquivo para. Como posso fazer isso?

Eu criei esta solução:

find . -name '*.json' | xargs -i mv {} $(cat {} | jq '.billingAccountList[0]' | tr -d \").json

Mas isso não funciona, porque cat está tentando interpretar o {}. Eu estava esperando que os xargs o interpretassem. Isso me dá esse erro:

cat: {}: No such file or directory
    
por Daniel Kaplan 27.07.2018 / 01:35

3 respostas

1

Use um loop para manipular os arquivos, um por um.

Por exemplo, com while read :

find . -name '*.json' | while read fname; do
    newname=$(jq -r '.billingAccountList[0]' "${fname}").json
    mv "${fname}" "${newname}"
done

Usar for pode ser possível, mas é mais sensível a espaços nos nomes dos arquivos:

for fname in $(find . -name '*.json'); do
    ... (same as above) ...

Observe também que você está movendo os arquivos para o diretório atual , pois o caminho original está sendo removido, portanto, se você quiser manter a estrutura do diretório:

find . -name '*.json' | while read fname; do
    fdir=$(dirname "${fname}")
    newname=$(jq -r '.billingAccountList[0]' "${fname}").json
    mv "${fname}" "${fdir}/${newname}"
done

Espero que isso ajude!

UPDATE : usando jq -r como sugerido por @steeldriver. Obrigado!

    
por 27.07.2018 / 03:00
2

Você deve ser capaz de usar jq -r para gerar strings brutas (sem aspas) - em vez de retirar aspas com tr

Além disso, assumirei que você deseja renomear os arquivos em relação ao diretório pai (por exemplo, se o valor .billingAccountList[0] em path/to/file.json for foo , o novo nome deverá ser path/to/foo.json em vez de foo.json ) e que sua implementação de find tem -execdir

Então, eu faria algo como

find . -name '*.json' -execdir sh -c '
  echo mv -- "$1" "$(jq -r ".billingAccountList[0]" < "$1").json"
' find-sh {} \;

ou (pelo menos com GNU find ) mais eficientemente

find . -name '*.json' -execdir sh -c '
  for f; do echo mv "$f" "$(jq -r ".billingAccountList[0]" < "$f").json"; done
' find-sh {} +

Remova o echo quando estiver satisfeito por estar fazendo a coisa certa.

    
por 27.07.2018 / 03:37
0

Com zsh zmv (para melhor tratamento de conflitos):

autoload zmv
zmv -n '(**/)*.json(#qD.)' '$1$(jq -r '.billingAccountList[0]' < $f).json

(remova -n quando feliz).

    
por 27.07.2018 / 08:38

Tags