Ubuntu – Print sub-folder name and content of result.txt to .csv

bashcommand linefind

I have a folder which has multiple sub-folders and sub sub folders. I want to print the content of a file called result.txt which is present in many sub folders or sub sub folders into a csv file along with the name of the sub-folder.

That means if the files named result.txt are in

abc/def/result.txt
efg/result.txt

Then I need a csv file which should have

1. abc   content of its result.txt
2. efg    content of its result.txt

and so on.

I started with the following find command

find . -iname 'result.txt' "a portion of path" "content">final.csv

How should I proceed from here ?

Note: (8th December, 2017) Although the below solutions display the content properly on the terminal , none of them work when I add >final.csv. As already mentioned, my result.txt has mutilines. The content of a particular result.txt gets spilled to different cells rather than being in a single cell. Any suggestions ?

Best Answer

I think find is the right choice:

find */ -name "result.txt" -exec bash -c 'printf "%s,%s\n" "${0%%/*}" "$(cat $0)"' {} \;

Example run

$ echo r1 >a/b/result.txt
$ echo r2 >c/result.txt
$ tree
.
├── a
│   └── b
│       └── result.txt
└── c
    └── result.txt
$ find */ -name "result.txt" -exec bash -c 'printf "%s,%s\n" "${0%%/*}" "$(cat $0)"' {} \;
a,r1
c,r2

Explanations

This find command searches every file in or under the current directory of the name result.txt and executes the printf command in a bash subshell. The printf command prints the subdir's name, a comma and the file content followed by a \newline. If you want to write this output to a file, just append e.g. >final.csv to the command.

Even simpler

is the -printf approach suggested by steeldriver:

$ find */ -name 'result.txt' -printf '%H,' -exec cat {} \;
a/,r1
c/,r2

This prints an additional slash in the first column which you can easily remove by piping the output through e.g. sed 's|/,|,|'.

Merging multiline result.txt content into one cell

To replace newline characters with e.g. spaces just replace cat with sed ":a;N;\$!ba;s/\n/ /g" in one of the above commands, e.g.

$ find */ -name "result.txt" -exec bash -c 'printf "%s,%s\n" "${0%%/*}" "$(sed ":a;N;\$!ba;s/\n/ /g" $0)"' {} \;
a,r1 r1
c,r2

If you want some other string as the delimiter replace the / / part with /your_delimiter/, but keep the slashes.

Related Question