I need a solution(s) on how to change to the latest directory that has similar naming conventions as others. For example:
Folder names are as follows...
parent_directory ---> folder100.000.200
----------------------------folder100.000.201
----------------------------folder100.000.202
----------------------------folder100.000.203
Using linux shell, I'm trying to navigate to the parent_directory then to the latest folder (folder100.000.203) without having to change the script every single day (folders are added regularly).
The old solution was:
FOLDER=folder100.000.$1
cd parent_folder/${FOLDER}
But this no longer works. I understand that $1 is a positional parameter, but fail to understand why it worked previously and not now. Any help with this would be greatly appreciated.
EDIT:
So I figured out the old script was passing a value into the script, which is where $1 was coming from. When I ran the script, I forgot I had to pass in the version number, but is there a way around me having to specify this?
./script.sh 203
This is the current working solution, but I still want to automate finding the number and passing it in.
If the folder you want is the most recently created (regardless of its name) then you can use ls -c to sort by ctime descending. So, perhaps something like:
cd $(ls -c | head -1)
I think I have found a solution, but I wanted more eyes on it to verify.
cd $(ls -dr */ | grep 'folder100.000' | head -1
This solution returns the directory (-d */) that has 'folder100.000' (grep 'folder100.000') in it's name and sorts it in reverse order (-r), which returns the highest build number (head -1). So this code returns:
folder100.000.203
Since the only thing that changes is the final 3 numbers, is this a proper solution or should I find another way of finding the latest version folder?
Side note: These commands will be running in ftp
Related
I'm trying to script something that isn't outputting quite correctly with the date command. Here's the contents of what I have thus far:
#!/bin/bash
# Get RPM manifest
# Output written to /tmp
NOW=$(date +%D)
rpm -qa --qf="%{NAME}.%{ARCH}\n" | sort > /tmp/$HOSTNAME.RPM_Manifest.$NOW.txt
When I run this script, I get this message:
[root#linmachine1 ~]# sh /usr/local/bin/rpm_manifest.sh
/usr/local/bin/rpm_manifest.sh: line 7: /tmp/linmachine1.RPM_Manifest.03/01/17.txt: No such file or directory
I suspect the problem is in how the date formatting within the NOW variable I'm defining may be the culprit. I've tried with and without quotes and get the same thing. Looking at the man pages, I didn't see a way to change the default behavior such that the forward slashes would be replaced by dots, as I believe this is where the problem lies.
EDIT: Thanks for all of your responses. I'm not real sure why this was downvoted though. I asked a legitimate question. What gives?
Yes, you shouldn't have slashes in a file name.
Use:
now=$(date "+%d.%m.%Y")
rpm -qa --qf="%{NAME}.%{ARCH}\n" | sort > "/tmp/$HOSTNAME.RPM_Manifest.$now.txt"
instead, or replace the . with whatever you prefer
I am a beginner to UNIX. Im trying to create a bash script that lists the 'head' of every file in a specified directory but ive tried everything and it doesnt seem to work. How would i do it. Below is the code i currently have in my script. I intent to add more to the script later on but need this to work first.
numberOfLines=$1
directoryName=$2
head $numberOfLines $directoryName
Try this:
head $directoryName/* -n $numberOfLines
You are calling the head command in a wrong way.
Compare your code to the manual page.
I would use the find command:
find "$directory" -maxdepth 1 -type f -exec head -n "$numberOfLines" {} \;
This ensures that head will be executed only on files and not directories.
Head works on a file (or group of files), not a directory, so you need to adjust your directoryName variable so that you're telling the shell interpreter you mean "every file in this directory" and not a directory.
The easiest way would be to add "/*" to the directoryName, changing your third line to this:
head $numberOfLines ${directoryName}/*
Example:
myshell:tmp gdalton$ ./script.sh -2 hello
==> hello/file1 <==
file 1
==> hello/file2 <==
file 2
file 2
Note that you will need to invoke your first parameter with the dash as I did in the example because of the syntax for the head command. You could easily fix this in your code using the change I made to fix your code as a jumping point... I'd strongly advise you check the man pages for head so you can figure out how to structure your shell commands; they often contain a wealth of options for these commands.
man head
Good luck.
Of course there would be little to no point to this, but the idea struck me today and I haven't really seen anything on it. I suppose it could be a good exercise on efficiency, especially if you consider every directory under (/).
First idea that comes to mind:
Pipe a recursive ls command to a file, use wc to count number of lines, then generate a random integer and use it to pick a line from the file you just created.
ls -R / >> file_list.txt
count=$(wc -l file_list.txt)
etc. You can get it from here.
Is there a less brute-force way to do this?
#!/bin/ksh
THIS_SCRIPT=$(/usr/bin/readlink -f $(echo $0 | /bin/sed "s,^[^/],$PWD/&,"))
echo $THIS_SCRIPT
I'm stuck using ksh but would prefer a solution that works in bash too (which I think this does).
Entry #28 in the bash FAQ:
How do I determine the location of my script? I want to read some config files from the same place.
There are two prime reasons why this issue comes up: either you want to externalize data or configuration of your script and need a way to find these external resources, or your script is intended to act upon a bundle of some sort (eg. a build script), and needs to find the resources to act upon.
It is important to realize that in the general case, this problem has no solution. Any approach you might have heard of, and any approach that will be detailed below, has flaws and will only work in specific cases. First and foremost, try to avoid the problem entirely by not depending on the location of your script!
...
Using BASH_SOURCE
The BASH_SOURCE internal bash variable is actually an array of pathnames. If you expand it as a simple string, e.g. "$BASH_SOURCE", you'll get the first element, which is the pathname of the currently executing function or script.
I've always done:
SCRIPT_PATH=$(cd `dirname ${0}`; pwd)
I've never used readlink before: is it Gnu only? (i.e. will it work on HP-UX, AIX, and Solaris out of the box? dirname and pwd will....)
(edited to add `` which I forgot in original post. d'oh!)
(edit 2 to put on two lines which I've apparently always done when I look at previous scripts I'd written, but hadn't remembered properly. First call gets path, second call eliminates relative path)
(edit 3 fixed typo that prevented single line answer from working, back to single line!)
Why didn't I think to try this before I asked the question?
THIS_SCRIPT=$(/usr/bin/readlink -nf "$0")
Works great.
In macOS I use (edit: only works if you run the script from where the script actually is!)
my_script=$(pwd)/$(basename $0)
I have attempted to run the following bash script on my internet tablet (Nokia N810 running on Maemo Linux). However, it doesn't seem that it is running, and I have no clue of what's wrong with this script (it runs on my Ubuntu system if I change the directories). It would be great to receive some feedback on this or similar experiences of this issue. Thanks.
WORKING="/home/user/.gpe"
SVNPATH="/media/mmc1/gpe/"
cp calendar categories contacts todo $WORKING
What actually happens when you run your script? It's helpful if you include details of error messages or behavior that differs from what's expected and in what way.
If $WORKING contains the name of a directory, hidden or not, then the cp should copy those four files into it. Then ls -l /home/user/.gpe should show them plus whatever else is in there, regardless of whether it's "hidden".
By the way, the initial dot in a file or directory name doesn't really "hide" the entry, it's just that ls and echo * and similar commands don't show them, while these do:
ls -la
ls -d .*
ls -d {.*,*}
echo .*
echo {.*,*}
The bash cp command can copy multiple sources to a single destination, if it's a directory.
Does the directory /home/user/.gpe exist?
Bear in mind that the leading dot in the name can make it hidden unless you use ls -a
I tried your commands in cygwin:
But I used .gpe instead of /home/user/.gpe
I did a touch calendar categories contacts todo to create the files.
It worked fine.
If that's the entirety of your script, it's missing two. possible three, things:
A shebang line, such as #!/bin/sh at the start
Use of $SVNPATH. You probably want to cd $SVNPATH before the cp command. Your script should not assume the current working directory is correct.
Possibly execute permission on the script: chmod a+x script
Do you already have the /home/user/.gpe directory present? And also, try adding a -R parameter so that the directories are copied recursively.