Reputation: 701
I have some questions about using the basename function in bash.
I have some paths stored in a file called filename2.txt
, it looks something like this:
/data/sequedas/Miseq2/17031_M0446
/data/sequedas/Miseq2/17022_N0213
/data/sequedas/Miseq2/28103_N3123
...
So I was running a loop trying to do something to each of the folder above:
while read line;
do interop_imaging_table $line > basename $line ;
done < filename2.txt
Basically I want to use basename $line
to remove everything in the path of the filename except the last part. So that I would be left with the following in the filename by using basename $line
:
17031_M0446
17022_N0213
28103_N3123
But unfortunately it doesn't work for some reasons. Basically the output will all output to the file called basename
. But I was hoping it would output separately to files called 17031_M0446
, 17022_N0213
, ....
Upvotes: 0
Views: 1102
Reputation: 16216
Here are two ways to do that.
As a note, I've added some extra quotes to better support any spaces or other unexpected characters in your paths.
First, command substitution:
while read line
do interop_imaging_table "$line" > "$(basename "$line")"
done < filename2.txt
(Don't worry, the "$(…)"
structure allows one level of nested quotes even though SO's syntax highlighting doesn't understand it. I'm not sure if that works with the deprecated "`…`"
syntax.)
Second, built-in substitution via parameter expansion:
while read line
do interop_imaging_table "$line" > "${line##*/}"
done < filename2.txt
"${line##*/}"
instructs the shell (bash in your case, but this is POSIX-compliant so it'll work in nearly any shell) to remove characters from the front of the string up to (and including) the final /
character. (If you were to say "${line#*/}"
then you'd remove characters from the front of the string up to (and including) the first /
character.
Similarly, "${line%%/*}"
would strip the text from the end up to (and including) the first /
character (in this case, you'd end up with empty strings since they start with /
). "${line%/*}"
is basically the same as "$(dirname "$line")"
in that it removes all characters starting with the final /
.
To add a suffix to the file name, just add it before the final quote, like "$(basename "$line").txt"
or "${line##*/}.txt"
Upvotes: 1
Reputation: 781994
You have to use $()
to substitute the output of a command back into the command line:
interop_imaging_table "$line" > "$(basename "$line")"
What you wrote is equivalent to writing
interop_imaging_table $line $line > basename
because >
just uses the next word as the filename.
You should also remember to quote variables unless you specifically need word splitting to be done on the result.
Upvotes: 0