0

Trying to run a script that will fetch all directories, and files containing these directories, and logs data onto a .CSV file.

So, if I were to have structure like: mainDir.dir -> [sub1.dir -> file01.png, sub2.dir -> file02.png] , I would get a CSV of

  • dir; file
  • sub1; file01.png
  • sub2; file02.png

This is the script I currently have

for dir in */ .*/ ; 
do
    for entry in $dir
    do
        path="$entry"
        empty=""
        file="${$dir/$empty}"
        echo -e "$dir;$file;" >> file.csv
    done

done
3
  • What's wrong with ls -AR ?
    – Alex M
    Commented Sep 26, 2018 at 12:49
  • Using the output of ls to get filenames is a bad idea. It can lead to malfunctioning and even dangerous scripts. This is because a filename can contain any character except / and the nullcharacter, and ls does not use either of those characters as delimiters, so if a filename has a space or a newline, you will get unexpected results.
    – Alex
    Commented Sep 26, 2018 at 12:53
  • You could also look at find?
    – Gem Taylor
    Commented Sep 26, 2018 at 14:23

2 Answers 2

1

find is useful for processing many files recursively.

Command

find . -type f -execdir sh -c "pwd | tr -d '\n' >> ~/my_file.csv; echo -n ';' >> ~/my_file.csv; echo {} | sed -e 's/^\.\///' >> ~/my_file.csv" \;

Note: make sure you do not give a relative path to the output CSV file. execdir changes the working directory (and that is what makes pwd work).

Breakdown

find . -type f find all files recursively starting here

-execdir sh -c "pwd | tr -d '\n' >> ~/my_file.csv; echo -n ';' >> ~/my_file.csv; For each file, execute in its directory pwd. Strip the newline and add directory name to output. Also add a semicolon, again with no newline.

echo {} | sed -e 's/^\.\///' >> ~/my_file.csv" \; Append filename to output. This time, leave newline, but by default find will place the ./ in front of the filename. The sed here removes it.

0

If you don't need more than one level deep, this seems to work

for i in **/*; do echo $i | tr / \; ; done >> file.csv
3
  • Can you explain? How can I replace now the file02.png with something like my-url.com/pictures/file02.png? I see that $i is the dir, but where is the file name?
    – Alex
    Commented Sep 26, 2018 at 13:16
  • After expansion you get "any file inside a directory". Inside the loop you get the full relative path, if that makes sense: 'sub1.dir/file01.png', tr replaces the slash with a semicolon
    – msg
    Commented Sep 26, 2018 at 13:37
  • @Alex what do you want to do exactly ? Process the csv ? In pure bash or other language ?
    – msg
    Commented Sep 26, 2018 at 16:43

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