K.Shajihan
K.Shajihan

Reputation: 19

How to create one output file for each file passed to a loop in bash?

I have a file that I pass to a bash command that will create an output in a loop like so:

for file in /file/list/*
do
    command
done

I wish to save the output that would have gone to standard out of each loop to a text file in my working directory. Currently I am trying this:

for file in /file/list/*
do
    command | tee "$file_command output.txt"
done

What I expect to see are new files created in my current directory titled file1.txt_commandoutput.txt, file2.txt_commandoutput.txt, etc. The output of the command should be saved as a different file for each file. However I get only one file created and it's called ".txt" and can't be opened by any standard software on Mac. I am new to bash scripting, so help would be much appreciated!

Thanks.

Upvotes: 0

Views: 1114

Answers (3)

randomir
randomir

Reputation: 18687

You have two issues in your script.

First, the wrong parameter/variable is expanded (file_command instead of file) because it's followed by a character that can be interpreted as part of the name (the underscore, _). To fix it, enclose the parameter name in braces, like this: ${file}_command (see Shell Parameter Expansion in bash manual).

Second, even with fixed variable name expansion, the file won't be created in your working directory, because the file holds an absolute pathname (/file/list/name). To fix it, you'll have to strip the directory from the pathname. You can do that with either basename command, or even better with a modified shell parameter expansion that will strip the longest matching prefix, like this: ${file##*/} (again, see Shell Parameter Expansion, section on ${parameter##word}).

All put together, your script now looks like:

#!/bin/bash
for file in /file/list/*
do
    command | tee "${file##*/}_command output.txt"
done

Also, to just save the command output to a file, without printing it in terminal, you can use a simple redirection, instead of tee, like this: command > "${file##*/}_com...".

Upvotes: 0

John Goofy
John Goofy

Reputation: 1419

If you are not aware of xargs, try this:

$ ls
file
$ cat > file
one
two
three
$ while read this; do touch $this; done < ./file
$ ls
file  one  three  two

Upvotes: 0

Joan Rieu
Joan Rieu

Reputation: 1019

Your problem comes from the variable name you're using:

"$file_command_output.txt" looks for a variable named file_command_output (the dot cannot be in the variable name, but the alphanumerical characters and the underscore all can).

What you're looking for is "${file}_command_output.txt" to make the variable name more explicit.

Upvotes: 2

Related Questions