Identify .json files with empty arrays?

201

Solution 1

Jq would be the right tool for processing/analyzing JSON data:

for f in *.json; do
    if jq -e 'keys_unsorted as $keys
              | ($keys | length == 1) 
                and .[($keys[0])] == []' "$f" > /dev/null; then
        mv "$f" error_dir/
    fi
done

Solution 2

mkdir -p error_folder &&
for json in ./*.json; do
    if jq -e '.. | select(type == "array" and length == 0)' "$json" >/dev/null
    then
        mv "$json" error_folder/
    fi
done

This is more or less the same approach as Roman took in his answer, but uses a different jq expression.

The expression ..|select(type == "array" and length == 0) will recurse the full JSON structure and select all bits of it that are zero-length arrays (anywhere, at any depth).

If the select() is successful, then jq will exit with a zero exit status (success), which means that the JSON document contains an empty array somewhere (or the file is totally empty). This triggers a moving of the document to error_folder in the script.


From comments below it is clear that the user is only interested in the WarehouseActivity array.

My code with a modified jq expression:

mkdir -p error_folder &&
for json in ./*.json; do
    if jq -e '.. | .WarehouseActivity? | select(type == "array" and length == 0)' "$json" >/dev/null
    then
        mv "$json" error_folder/
    fi
done
Share:
201

Related videos on Youtube

Vidhya
Author by

Vidhya

Updated on September 18, 2022

Comments

  • Vidhya
    Vidhya over 1 year

    I have an XML as below. In this XML all the attributes are available as elements.

    <Dress>
        <ID>001</ID>
        <shirts>
            <product>
                <ID>345</ID>
                <Name>tee</Name>
                <Serial>5678</Serial>
            </product>
            <product>
                <ID>456</ID>
                <Name>crew</Name>
                <Serial>4566</Serial>
            </product>       
        </shirts>
        <pants>
            <product>
                <ID>123</ID>
                <Name>jeans</Name>
                <Serial>1234</Serial>
                <Color>blue</Color>
            </product>
            <product>
                <ID>137</ID>
                <Name>skirt</Name>
                <Serial>3455</Serial>
                <Color>black</Color>
            </product>
        </pants>
    </Dress>
    

    I need convert this XML as:

    <Dress ID="001">
        <shirts>
            <product ID="345" Name="tee" Serial="5678"/>
            <product ID="456" Name="crew" Serial="4566"/>
        </shirts>
        <pants>
            <product ID="123" Name="jeans" Serial="1243" Color="blue"/>
            <product ID="123" Name="skirt" Serial="3455" Color="black"/>
        </pants>
    </Dress>
    

    Basically I need to convert the elements to attributes. How do I do this using c#?

    • Chandan Kumar
      Chandan Kumar about 7 years
      are u sure you are going to modify the source file ? then why c# tag?
    • Vidhya
      Vidhya about 7 years
      Yes. The source file has to be modified. I need to do this using c#.
    • Chandan Kumar
      Chandan Kumar about 7 years
      what you have tried so far?
    • Chandan Kumar
      Chandan Kumar about 7 years
      Did you got your solution? See my answer. It generates output as you expected
    • dirkt
      dirkt about 6 years
      Did you try with jq?
    • Stéphane Chazelas
      Stéphane Chazelas about 6 years
      { "x": [[],[]] } would have an array made of two empty arrays. Should that also be flagged?
    • Kavin Palaniswamy
      Kavin Palaniswamy about 6 years
      @RomanPerekhrest yes its same across all the files and no, i haven't tried the jq option...am gonna try the code posted by you and revert back to you.
    • Kavin Palaniswamy
      Kavin Palaniswamy about 6 years
      @StéphaneChazelas well, there hasn't been any such case yet. Just one empty array.
    • Kavin Palaniswamy
      Kavin Palaniswamy about 6 years
      @dirkt i wasn't aware of the jq till date, i just installed it on my machine.
  • Chandan Kumar
    Chandan Kumar about 7 years
    you have missed ID="001" attribute for the <Dress> root element
  • Terry Lennox
    Terry Lennox about 7 years
    @uɐpuɐɥƆ good spot! I don't think this would need a huge change to fix though.
  • Stéphane Chazelas
    Stéphane Chazelas about 6 years
    Note that jq (at least my version) also returns true here for empty files and files made entirely of blanks (which the OP may also want to consider as errors anyway).
  • Kavin Palaniswamy
    Kavin Palaniswamy about 6 years
    Hi @Kusalananda , i gave this code a try but it is not working as expected. It ends up moving all the json files in that folder including the empty json file.
  • Kavin Palaniswamy
    Kavin Palaniswamy about 6 years
    this works great! It identifies the empty files and moves them to the error folder. To start with i wasn't even aware of the jq command, i had to install the jq package in my machine to get this to work. Thanks a lot. Really appreciate the help.
  • Kusalananda
    Kusalananda about 6 years
    @KavinPalaniswamy Then all files contain at least one empty array somewhere, or you have an error in your script. I've tested the code in my answer.
  • Kavin Palaniswamy
    Kavin Palaniswamy about 6 years
    @Kusalananda Yes, you are correct the json files do have empty arrays. I was looking to identify the json files which have only the below : { "WarehouseActivity": [] } Don't really want to identify all the empty arrays in the json files. But great solution. I will use this when i need to identify all the empty arrays . Thanks a lot. really appreciate your help.
  • Kusalananda
    Kusalananda about 6 years
    @KavinPalaniswamy Updated my answer.
  • RomanPerekhrest
    RomanPerekhrest about 6 years
    @KavinPalaniswamy, you're welcome
  • Kavin Palaniswamy
    Kavin Palaniswamy about 6 years
    Hey! There is a scenario when there is no such file , am getting a error message "jq: error: Could not open file *.json: No such file or directory" . For now am just suppressing it. Any way around it ?
  • RomanPerekhrest
    RomanPerekhrest about 6 years
    @KavinPalaniswamy, it seems that you are not applying the above approach in exact manner. for f in *.json; will iterate through existed .json files (unless you don't have folders which end with .json)
  • Kavin Palaniswamy
    Kavin Palaniswamy about 6 years
    Sorry for the delayed response. Well i think i didn't explain myself well. When the folder is completely empty and there are no json files i get the error :jq: error: Could not open file Test_*.json: No such file or directory . I have implemented the exact same code given by you. As a work around i am just check if any file exist and then am running your code. This does't throw any error. Any better way to implement this sir?