This is a bit of a crazy one, but I am wondering if it is even possible.

I have maybe 300 folders in my /var/www folder that were all renamed to the same name [Name](Num) so kindred (19) for example.

Almost every single one of these folders has a file called package.json which all have a name key value pair which then has the name of the project in side that.

  "name": "a useful project name",
  "main": "src/index.js",

I would like the folder that contains the package.json to be renamed to whatever the value of "name" is inside the package.json file.


One of the better tools to use when you need to parse json files is jq. That makes it easy to extract the name field from the package.json file in a directory. Performing the rename is a simple bit of shell scripting:

$ cd /var/www
$ for d in */; do  # *1
>    if [ -f "${d}package.json" ]; then  # *2
>        new_name=$(jq -e -M -r .name "${d}package.json")  # *3
>        if [ $? -eq 0 ] && ! [ -e "${new_name}" ]; then  # *4
>            mv "${d}" "${new_name}"  # *5
>        fi
>    fi
> done

Some notes:

*1: */ expands to all the directories in the current directory. Each directory name will include a / on the end, so we do not put one in later at *2 and *3.

*2: Only process directories that have a package.json file.

*3: Invoke jq to extract the name field from package.json. We invoke jq with -r to output raw strings (i.e. leave off the double quotes), with -M to not have colored output, and -e to have jq exit with an error if there is no name field.

*4: Check that jq ran successfully (there was a name field) and that the new name for the directory does not already exist. You may want to split these up and add an else if you want to output an error message for the two cases where you're skipping the rename.

*5: Rename the directory.

For a test run, I'd put echo in front of the mv command at *5 and check the output to see that the renaming looks right. I haven't tested this myself as I don't have a bunch of directories with package.json files.

  • I changed ` $? -ne 0` to ` $? -ne 1` and it worked a treat :D Aug 26 '18 at 19:32
  • 1
    @JamieHutber Yeah, sorry. Stupid typo. I've changed it from -ne to -eq which is better than checking -ne 1 as jq could return a different error code.
    – camh
    Aug 27 '18 at 2:27

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.