[SOLVED] Changing File Names to Include Part of the Directory Name
Linux - GeneralThis Linux forum is for general Linux questions and discussion.
If it is Linux Related and doesn't seem to fit in any other forum then this is the place.
Notices
Welcome to LinuxQuestions.org, a friendly and active Linux Community.
You are currently viewing LQ as a guest. By joining our community you will have the ability to post topics, receive our newsletter, use the advanced search, subscribe to threads and access many other special features. Registration is quick, simple and absolutely free. Join our community today!
Note that registered members see fewer ads, and ContentLink is completely disabled once you log in.
If you have any problems with the registration process or your account login, please contact us. If you need to reset your password, click here.
Having a problem logging in? Please visit this page to clear all LQ-related cookies.
Get a virtual cloud desktop with the Linux distro that you want in less than five minutes with Shells! With over 10 pre-installed distros to choose from, the worry-free installation life is here! Whether you are a digital nomad or just looking for flexibility, Shells can put your Linux machine on the device that you want to use.
Exclusive for LQ members, get up to 45% off per month. Click here for more info.
Changing File Names to Include Part of the Directory Name
I want to do something similar to what I found in this thread. I have scripts to compile and install packages, all names "build," that are in directories named for the package.
I need to add that this is the first time I've used `cut` so I'm just learning it.
I can achieve what I want if I have two cut statements in a loop. The first is
Code:
newname=$(echo $dir | cut -f1 -d.)
which gives, for example shadow-4. I can reduce this to only "shadow" by passing
Code:
-d-
in a second command to `cut`, but that doesn't work so well with packages like "module-init-tools" that have a series of fields separated by "-". And packages have a variable number of fields like this.
Currently, only the "two command" method gives me what I want. I'm hoping someone can suggest or point me to something that can reduce this to only one command.
Thanks. I had discovered that expansion last night and was playing with it. But you have suggested a much simpler substitution. I was using [-0-9][0-9]. Yours is much simpler.
The situation now is that I cannot get it to run in a loop.
If in a script or straight to a terminal, or script without a loop, I run
for dir in shadow-4.1.4.3 module-init-tools-3.12
do
pattern=-*
echo $pattern
newname=${dir%%$pattern}
echo $newname
done
produces:
Code:
-*
shadow
-*
module
even if it would be safer to enclose -* in single quotes or use it directly in the parameter substitution as catkin showed. Please, write down the exact statements that give this error.
In moving around in terminals, I can't find the commands that cause the error. But here's a copy of the script that I was testing which produces the errors:
Code:
! /bin/bash
# A script to remove all but the actual names of a package.
# shadow-4.1.4.3 --> shadow
pattern=-*
echo "pattern =" $(pattern)
for dir in `ls /home/dan/LFS-6.8/cut-test`
do
echo $dir
newname=${dir%%$pattern}
echo $(newname)
done
I copied and pasted your commands into a terminal and all was well, and then ran them in a script. The script succeeded. I did learn, when "module-init-tools-3.12" became "module" I needed to use '%' instead of '%%'. It's these "naggy" mistakes that cause me frustration and I'm sure I did something like that in the script and the commands that I was using in the terminal.
The only difference I see between things now is that $parameter is declared outside the loop instead of inside of it. I've declared variables before outside loops, but I've never encountered something like this until now. Am I missing something conceptual or can you see a "typo" that I'm missing.
At any rate, since scripting works, I can proceed with my project.
Here is the offending line. pattern is inside command substitution, therefore it is interpreted as a command and it's not found by the shell. The correct syntax for variable reference (or parameter substitution) is
Code:
echo "pattern =" ${pattern}
The same for echo $(newname) below. Just a typo, I guess.
Hmmmmmm! More than just a typo. Conceptual error. I didn't quite understand your remark
Quote:
pattern is inside command substitution
so I changed $(pattern) and $(newname) to $pattern and $newname, ran the script and got the desired results.
I've never been quite clear on the use of ( ) and { } in variables and patterns. I've just used what works. Looks like I'll be nosing around in the "The Bash Reference Guide" and "The Advanced Scripting Guide" again today.
In a few words: when you reference a variable (that is you want to retrieve the value of that variable) the correct syntax is:
Code:
${variable_name}
but you can omit the brackets, except in some cases where they are mandatory to obtain the desired result. For example if you want to embed the value of the variable in a string you have to tell the shell where the variable name terminates, otherwise any other valid character is considered part of the name itself. Example: suppose you have a variable called my_var and you want to embed its value in a string:
This stupid example, just show you that the shell tries to reference a variable called my_var_change_it_and_this_string_will_change, whereas if you use brackets:
the shell references the variable my_var correctly.
Regarding command substitution, it is another story. It serves to substitute the result of a command, not the value of a variable:
Code:
echo Today is $(date)
will substitute the result of the date command, not the value of an hypothetical variable called date.
Indeed, you will find a lot of details on the aforementioned documentation.
colucix, thank you so much for this. It is the best and most understandable discussion of variables and substitution that I've ever encountered. I see now why I wasn't getting the results I wanted.
This is, in fact, so important to me that I'm going to "bookmark" this response so that I can refer to it in the future when I have questions.
I just noticed what you have in your "signature block."
Quote:
Complex problems have simple, easy to understand, wrong answers. (Henry Louis Mencken)
This appeals to me since I'm a great fan of Occam's Razor--the simplest solution is almost always the best. But then the situation is in identifying the simplest solution and that's where my signature block comes into play.
I changed my signature recently. Maybe you like my previous one:
Theory is when you know all and nothing works. Practice is when all works and nobody knows why. In this case we have put together theory and practice: nothing works... and nobody knows why! (Albert Einstein)
And I am an estimator of the Occam's Razor principle, too!
LinuxQuestions.org is looking for people interested in writing
Editorials, Articles, Reviews, and more. If you'd like to contribute
content, let us know.