4

I want to extract all image names with sub folder names into a CSV file.

I have this folder structure

Desktop/Wall Arts Product Images/framed-posters/landscape/animals-and-birds/Bighorn/Bighorn.jpg
Desktop/Wall Arts Product Images/framed-posters/landscape/animals-and-birds/Lion/Lion.jpg
Desktop/Wall Arts Product Images/framed-posters/landscape/animals-and-birds/Giant-Panda/Giant-Panda.jpg
Desktop/Wall Arts Product Images/posters/landscape/Automobiles/Best-Deisgner-Jack-Daniel-Chopper/Best-Deisgner-Jack-Daniel-Chopper.jpg
Desktop/Wall Arts Product Images/posters/landscape/Automobiles/Ford-Mustang-Cars-Classic/Ford-Mustang-Cars-Classic.jpg
Desktop/Wall Arts Product Images/framed-posters/potrait/gods/Mukkunda/Mukkunda.jpg

and many more.

I run this command but it gives only folder name posters and framed-posters

'ls' | sed -e 's/^/"/' -e 's/$/"/' > files.csv

The desired output is like -->

    Image name,category,subcategory,type

    Bighorn,landscape,animals and birds,framed-posters
    Lion,landscape,animals and birds,framed-posters
    Giant-Panda,landscape,animals and birds,framed-posters
    Best-Deisgner-Jack-Daniel-Chopper,landscape,Automobiles,posters
    Ford-Mustang-Cars-Classic,landscape,Automobiles,posters
    Mukkunda,potrait,gods,framed-posters

How can I get the desired output in CSV file format?

1

Try with this:

find ~/Desktop -iname "*.jpg" -exec ls {} + | awk -F'/' ' BEGIN { OFS=", "; print "Image Name", "Category", "Subcategory", "type"} { print $(NF-1),$4, $5, $3 "" }' 

If you want to remove special character from image name, make use of below code:

find ~/Desktop -iname "*.jpg" -exec rename 's/[^a-zA-Z0-9.\/-]//g' {} +

Tweak it as per the output.

  • It is working fine .Only One issue it there.It is showing all ._African-Elephant-1.jpg African-Elephant-1.jpg ._African-Elephant-2.jpg African-Elephant-2.jpg ._African-Elephant-3.jpg African-Elephant-3.jpg ._African-Elephant-4.jpg African-Elephant-4.jpg ._African-Elephant-5.jpg African-Elephant-5.jpg like this .I want only name "African-Elephant" one time – Urvashi Feb 8 '17 at 8:01
  • @Urvashi made changes to the script, try it out. – Rakesh.N Feb 8 '17 at 8:06
  • @Urvashi No problem, If helped upvote it and mark it as answered. – Rakesh.N Feb 8 '17 at 10:02
  • Done.I want one more help.I want to rename all images name which hhave special character.Then remove special character from image name .For Example image name is :Holy-#%@!-You-Are-40-Black then it should remove all special character and the new image name should be "Holy-You-Are-40-Black".I have code like sed "s/[!@#\$%^&*()\']//g" <<< "image name" – Urvashi Feb 9 '17 at 6:24
  • @Urvashi made changes to answer, check it out. – Rakesh.N Feb 9 '17 at 9:03
2

Just because we can, here's a way that uses sed to reverse the order of the fields:

find -name "*.jpg" | sed -rn 's|^.||; s|[^/]*.jpg||; :a h; s|.*/(.*)|\1|p; x; s|(.*)/.*|\1| ; ta' | tr '\n' ',' | sed 's/,,/\n/g ; s/,$/\n/; s/^,//'

Yeah I know O_O

But it works even if the directory structure is not consistent

Here it is more readably with comments:

find -name "*.jpg" | sed -rn '{    #get the files and pipe the output to sed
s|^.||                             #remove the leading .
s|[^/]*.jpg||                      #and the basename, since each image is in a directory of the same name
:a h                               #create a label a for this branch and put the lines into the hold space in their current state
s|.*/(.*)|\1|p                     #print only the last field
x                                  #switch the hold space and pattern space 
s|(.*)/.*|\1|                      #exclude the last field from the new pattern space, which won't do anything if there is only one field on each line
ta                                 #if the last s command did anything, then start again from the label (:a) (thus recursively going through the fields and printing them out on separate lines in reverse order)
}' | tr '\n' ',' | sed '{          # finally turn the newlines into commas, then clean up the mess
s/,,/\n/g ; s/,$/\n/; s/^,//
}'
1

try this command..

find . | awk -F/ '{print $(NF-1)","$(NF-3)","$(NF-2)","$(NF-4)}'
1

Assuming you have a consistent directory tree structure, the python script presented below will traverse the directory tree and output csv contents to stdout stream ( use > operator on command-line to output contents into new file, as in ./dir_tree_csv.py > output_file.csv ). It is to be placed into Wall Arts Product Images directory and executed from there.

#!/usr/bin/env python
from __future__ import print_function
import os,sys

def get_all_files(treeroot):
    file_list = []
    for dir,subdirs,files in os.walk(treeroot):
         for f in files: 
             if os.path.basename(__file__) in f: continue
             file_list.append(os.path.join(dir,f))
    return file_list

def main():
    top_dir="."
    if len(sys.argv) == 2: top_dir=sys.argv[1]
    files = get_all_files(top_dir)

    print("Image name,category,subcategory,type\n")

    for f in files:
        fields = f.split('/')
        fields.reverse()
        fields[2],fields[3] = fields[3],fields[2]
        print(",".join(fields[1:-1]))

if __name__ == '__main__' : main()

Test run:

# Replicated directory structure with only two of the files for simplicity
 $ tree
.
├── dir_tree_csv.py
├── framed-posters
│   └── landscape
│       └── animals-and-birds
│           └── Bighorn
│               └── Bighorn.jpg
└── posters
    └── landscape
        └── Automobiles
            └── Best-Deisgner-Jack-Daniel-Chopper
                └── Best-Deisgner-Jack-Daniel-Chopper.jpg

8 directories, 3 files
$ ./dir_tree_csv.py                                                                                   
Image name,category,subcategory,type

Best-Deisgner-Jack-Daniel-Chopper,landscape,Automobiles,posters
Bighorn,landscape,animals-and-birds,framed-posters

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.