How to get name of second last folder in linux - linux

I have to write a shell script in linux in which i have to pull the name of the second last folder of the given path. For example:-
/var/www/html/folder1/folder2/folder3
How can i get only the name of second last folder "folder2" using a command?
Note: My shell script is placed at root (/var/www/html)

Using awk:
awk -F/ '{print $(NF-1)}' <<< "/var/www/html/folder1/folder2/folder3"
Alternatively, call basename on the dirname.
basename "$(dirname /var/www/html/folder1/folder2/folder3)"

you can use sed to get it:
export some_path="/var/www/html/folder1/folder2/folder3"
export folder_place2=`echo $some_path | sed -e "s/.*\/\([^/]*\)\/[^/]*/\1/"`
echo $folder_place2

Related

.sh script doesn't return variable correctly

I have created a file called alias.sh in which I have put this code:
#!/bin/bash
OUTPUT="$(alias | awk -F'[ =]' '{print $2}')"
echo "${OUTPUT}"
Whenever I run the command alias | awk -F'[ =]' '{print $2}' in a terminal, it correctly returns a list of set aliases in my preferred format.
However, when I execute the script like $ ./alias.sh, it simply returns an empty line.
The script works if I replace the alias | awk -F'[ =]' '{print $2}' command with the ls command. It even preserves line breaks.
Can anybody help me understand why the script does not return the expected result?
The actual reason for the error is because alias is not expanded when the shell is not interactive,
From the man bash page,
[..] Aliases are not expanded when the shell is not interactive, unless the expand_aliases shell option is set using shopt [..]
add the line below to the top of the script for force the expansion manually.
shopt -s expand_aliases
and then source the script and not execute it,
#!/bin/bash
shopt -s expand_aliases
output=$(alias | awk -F'[ =]' '{print $2}')
echo "$output"
and now source the script as
. ./myScript.sh
You use $2 in the AWK script. However, that is replaced by the shell as the second argument to the shell script, which is nothing. You need to escape the dollar-sign, as in \$2. Or not use double-quotes " around the sub-shell.

'No such file or directory' error in sh, but the file exists?

I'm running a command to retrieve the location of a logfile using from a .sh bash script
rig=`forever list | grep 'server.*root.*\.log' | awk '{print $8}'`
echoing it prints:
echo $rig
/root/.forever/1cFY.log
But when I try to read the file (which exists) like so:
less $rig
I get:
/root/.forever/1cFY.log: No such file or directory
However if I manually enter the file name without my .sh script it works.
Any ideas?
Looks like you have grep configured to output color. Just drop the grep and use awk:
rig=$(forever list | awk '/server.*root.*\.log/{print $8}')

How to change a windows path to a linux path in all files under a directory using sed

I copied a directory structure from a windows box to a Linux box and I would like to use sed to replace c:\IBM\WebSphere with /opt/IBM/WebSphere in all files under this directory.
Any thoughts?
I think sed is a little inconvenient for that purpose, if you want to change the actual files you can use perl one-liner
perl -pi -e 's/c:\\IBM\\/\/opt\/IBM\//g' *
Add or adjust the paths according to what you need (add WebSphere if you want the replacement to change only these dirs)
Since sed can take any character as a delimiter, use
sed -e 's_\\_/_g'
to replace the \ to /.
sed -e 's_[Cc]:_/opt_g'
to replace the c: with /opt
You can string those together:
echo "C:\\IBM\\WebSphere" | sed -e 's_\\_/_g' -e 's_[Cc]:_/opt_g'
Output:
/opt/IBM/WebSphere
I don't see an awk solution, just add one:
awk -F'\' -v OFS='/' '$1=/^c:/?"/opt":$1'
test:
kent$ awk -F'\' -v OFS='/' '$1=/^c:/?"/opt":$1' <<<'c:\IBM\WebSphere'
/opt/IBM/WebSphere
echo "C:\Users\San.Tan\My Folder\project1" | sed -e 's/C:\\/mnt\/c\//;s/\\/\//g'
replaces
C:\Users\San.Tan\My Folder\project1
to
mnt/c/Users/San.Tan/My Folder/project1
in case someone needs to replace windows paths to Windows Subsystem for Linux(WSL) paths

Shell script to replace string dynamically

I am writing a shell script for linux which takes argument as port no.
inside file following is a line which needs to be updated:
define('NO_OF_PORTS',10);
I need to replace that 10 by the argument passed.
But this should be dynamic, like next time I pass new port no it must get updated.
Using sed:
s="define('NO_OF_PORTS',10);"
n=25
sed "s/\('NO_OF_PORTS',\)[0-9]*/\1$n/" <<< "$s"
define('NO_OF_PORTS',25);
To change inline in the file use:
sed -i.bak "s/\('NO_OF_PORTS',\)[0-9]*/\1$n/" file
You can use sed in the script to edit the file
sed -i s/NO_OF_PORTS\',[0-9]*/NO_OF_PORTS\',$1/ $2
1.txt has
define('NO_OF_PORTS',19)
shell script
#!/bin/sh
echo $1
sed -i -r '/NO_OF_PORTS/ s/'[0-9]+'/'$1'/g' 1.txt
run
linux:/home/test # ./replace_port.sh 78
linux:/home/test # cat 1.txt
define('NO_OF_PORTS',78)

Bash script to remove last three charater in a file name

For ex the file is this:
NBDG6_CDRCCN_4004_-TTNBDG6_CCN_51-140108-1433-802580.00.Blk32768Blk.CCN:00
I want to rename this file to:
NBDG6_CDRCCN_4004_-TTNBDG6_CCN_51-140108-1433-802580.00.Blk32768Blk.CCN
Using ${parameter%word} (Remove matching suffix pattern):
$ echo "$fn"
NBDG6_CDRCCN_4004_-TTNBDG6_CCN_51-140108-1433-802580.00.Blk32768Blk.CCN:00
$ echo "${fn%:*}"
NBDG6_CDRCCN_4004_-TTNBDG6_CCN_51-140108-1433-802580.00.Blk32768Blk.CCN
Using cut
$ echo $fn
NBDG6_CDRCCN_4004_-TTNBDG6_CCN_51-140108-1433-802580.00.Blk32768Blk.CCN:00
$ echo $fn |cut -d: -f1
NBDG6_CDRCCN_4004_-TTNBDG6_CCN_51-140108-1433-802580.00.Blk32768Blk.CCN
Using awk
echo $fn |awk -F : '{print $1}'
more ways...
According to the link here:
This should work:
awk '{old=$0;gsub(/...$/,"",$0);system("mv \""old"\" "$0)}'
provided the file name is given as input.
For eg:
ls -1 NBDG6_CDRCCN_4004_-TTNBDG6_CCN_51-140108-1433-802580.00.Blk32768Blk.CCN:00|nawk '{old=$0;gsub(/...$/,"",$0);system("mv \""old"\" "$0)}'
Rename file using bash string manipulations:
# Filename needs to be in a variable
file=NBDG6_CDRCCN_4004_-TTNBDG6_CCN_51-140108-1433-802580.00.Blk32768Blk.CCN:00
# Rename file
mv "$file" "${file%???}"
This removes the last three characters from filename.
Using just bash:
fn='NBDG6_CDRCCN_4004_-TTNBDG6_CCN_51-140108-1433-802580.00.Blk32768Blk.CCN:00'
mv "$fn" "${fn::-3}"
if you have Ruby
echo NBDG6_CD* | ruby -e 'f=gets.chomp;File.rename(f, f[0..-4])'

Resources