Renomeie arquivos com base no conteúdo JSON

3

Eu tenho dois conjuntos de arquivos;
file1.txt file1.json
file2.txt file2.json e file3.txt file3.json e ... e fileN.txt fileN.json

Os arquivos json contêm o seguinte formato:% {"ago": "59 sec ago", "base_time": 1401243133, "title": "Untitled", "type": "None", "retrieval_time": 1401624105, "id": "qwNAgvYZ"}

Eu quero renomear cada arquivoX.txt com o parâmetro vale "title" do respectivo arquivo fileX.json.

por ex.

rename fileX.txt -> Untitled

Eu posso filtrar esse valor da seguinte maneira; %código% Mas se eu encontrar um nome de arquivo existente, ele deverá renomear a si mesmo com um sufixo.

Por exemplo, digamos que exista um $ cat fileX.json | awk -F"\"" '{print $10}' existente. Portanto, o novo arquivo deve ser renomeado como Untitled.txt . Próximo encontro como Untitled-1.txt da mesma forma.

    
por user3148655 17.05.2016 / 17:13

1 resposta

2

Aqui está um script de shell simples e direto que usa o jsonpipe para fazer o que você deseja. Ele não usa nenhum recurso sh / bash sofisticado e faz apenas a verificação mínima de sanidade dos nomes de arquivos.

OBSERVAÇÃO: jq é muito mais capaz do que jsonpipe , mas jsonpipe é mais simples e fácil de usar quando você não usa Preocupe-se particularmente (ou queira saber) sobre a estrutura dos dados json e apenas deseje extrair um ou dois campos e / ou deseje usar os dados json com ferramentas de processamento de texto orientadas por linha como awk , sed , grep etc.

Um possível aprimoramento óbvio é usar printf com um campo inteiro com zero de preenchimento para renomear arquivos para nomes numerados com largura fixa, por exemplo, Untitled-0001.txt em vez de Untitled-1.txt . Vou deixar isso para você fazer se você quiser.

Como escrito, ele não renomeia nenhum arquivo. Ele só imprimirá o comando mv que usaria . Edite-o para remover o comando echo de antes de cada comando mv para que realmente renomeie os arquivos.

#! /bin/sh

for f in file*.txt ; do
  b=$(basename "$f" .txt)

  # ignore current .txt file if there's no matching .json file
  if [ -e "$b.json" ] ; then
    # extract the title field.
    title=$(jsonpipe < "$b.json" | 
            awk -F'\t' '$1=="/title" {gsub(/\"/,"",$2) ; print $2}')

    if [ -n "$title" ] ; then
      if [ ! -e "$title.txt" ] ; then
        echo mv -v "$f" "$title.txt"
      else
        # are there any other "$title-*.txt" filenames?
        others=$(find . -maxdepth 1 -name "$title-*.txt")
        if [ -z "$others" ] ; then
          echo mv -v "$f" "$title-1.txt"
        else
          # use version-sort to get highest $title- number used.
          highest=$(printf "%s\n" "$others" | sort -V | tail -n 1)
          hnum=$(printf "%s\n" "$highest" | sed -e 's/^.*-// ; s/\.txt$//')
          hnum=$(( highest_num + 1))
          echo mv -v "$f" "$title-$hnum.txt"
        fi
      fi
    fi
  fi
done

Exemplos de uso / prova de que funciona:

$ ls -l
total 8
-rw-rw-r-- 1 cas cas 132 May 19 23:47 file1.json
-rw-rw-r-- 1 cas cas   0 May 20 00:04 file1.txt
-rwxrwxr-x 1 cas cas 797 May 20 00:04 json-rename.sh

$ cat file1.json 
{"ago": "59 sec ago", "base_time": 1401243133, "title": "Untitled",
 "type": "None", "retrieval_time": 1401624105, "id": "qwNAgvYZ"}

$ ./json-rename.sh 
mv -v file1.txt Untitled.txt

$ touch Untitled.txt
$ ./json-rename.sh 
mv -v file1.txt Untitled-1.txt

$ touch Untitled-1.txt
$ ./json-rename.sh 
mv -v file1.txt Untitled-2.txt

$ touch Untitled-999.txt
$ ./json-rename.sh 
mv -v file1.txt Untitled-1000.txt
    
por 19.05.2016 / 16:32