Concatenation in shell script and use of 'basename'
bash, sed, shell
Solution
Analysis
There are multiple issues to address in your script. Let's take it step by step:
tempDir=./tmp/
logDir=./logs/
for file in $( find `echo $logDir` -type f )
This scheme assumes no spaces in the file names (which is not an unusual restriction; avoiding problems with spaces in names is relatively tricky). Also, there's no need for the `echo`; just write:
for file in $(find "$logDir" -type f)
Continuing:
do
name=eval basename $file
This runs the `basename` command with the environment variable `name` set to the value `eval` and the argument `$file`. What you need here is:
name=$(basename "$file")
where the double quotes aren't strictly necessary because the name can't contain spaces (but it's not a bad habit to get into to quote all file names because sometimes the names do contain spaces).
echo $name
This would echo a blank line because name was not set.
name=$(echo $name | sed 's/.$//')
If name was set, this would chop off the last character, but if the name was `A`, you'd have nothing left.
echo $tempDir
opFile=$tempDir$name
echo $opFile
done
Give or take double quotes and the fact that you've not added the `_tmp` suffix to `opFile`, there's nothing wrong with the rest.
Synthesis
Putting the changes together, you end up with:
tempDir=./tmp/
logDir=./logs/
for file in $(find "$logDir" -type f)
do
name=$(basename "$file")
echo "$name" # Debug only
echo "$tempDir" # Debug only
opFile="$tempDir${name}_tmp"
echo "$opFile"
done
That shows all the intermediate results. You could perfectly well compress that down to:
tempDir=./tmp/
logDir=./logs/
for file in $(find "$logDir" -type f)
do
opFile="$tempDir"$(basename "$file")"_tmp"
echo "$opFile"
done
Or, using a simpler combination of double quotes because the names contain no spaces:
tempDir=./tmp/
logDir=./logs/
for file in $(find "$logDir" -type f)
do
opFile="$tempDir$(basename $file)_tmp"
echo "$opFile"
done
The echo is there as a surrogate for the copy or move operation you plan to execute, of course.
EDIT: ...and to remove restrictions on file names containing spaces and globbing characters, do it as:
tempDir=./tmp/
logDir=./logs/
find "$logDir" -type f |
while IFS= read -r file
do
opFile="${tempDir}${file##*/}_tmp"
echo "$opFile"
done
It will still fail for file names containing newlines. If you want to handle that then investigate a solution using `find ... -print0 | xargs -0` or `find ... -exec`.
Problem
I want to read all file names form a particular directory and then create new files with those names by appending some string to them in another directory. e.g > 'A', 'B', 'C' are in 'logs' directory then script should create 'A_tmp', 'B_tmp', 'C_tmp' in 'tmp' directory what i am using is - ``` tempDir=./tmp/ logDir=./logs/ for file in $( find `echo $logDir` -type f ) do name=eval basename $file echo $name name=$(echo $name | sed 's/.$//') echo $tempDir opFile=$tempDir$name echo $opFile done ``` But what I understood is, $file is containing '\n' as last character and I am unable to concatenate the string. right now I am not creating files, just printing all the names. So, how I can remove the '\n' from the file name, and is my understanding correct ?