How to store or capture variable from one directory to another and execute with cut command in Linux - shell

I need to do as following, firstly I can read a server name from the text file line by line and do a grep command on it. The main task is to find the whole FQDN server name using only the hostname in the NB logs path and do other commands further. Here is the script I wrote but I am beginner in shell scripting and need your help. What do I missing here because I was thinking How to save a variable's value into another directory path and use it there? If I manually run these commands in command line it can give me what I do need it., thank you all..
#!/bin/sh
echo
echo "Looking for the whole backup client names?"
for server in `cat ./List_ServerNames.txt`;
do
cd /usr/openv/netbackup/logs/nbproxy/
return_fqdn=`grep -im1 '$server' "$(ls -Art /usr/openv/netbackup/logs/nbproxy/ | tail -n1 | cut -
d : -f8)" | cut -d " " -f 6 | cut -c -36 | cut -d "(" -f 1`
echo $return_fqdn
done
The output of script is down below:
Looking for the whole backup client names?

Related

Checking file existence in Bash using commandline argument

How do you use a command line argument as a file path and check for file existence in Bash?
I have the simple Bash script test.sh:
#!/bin/bash
set -e
echo "arg1=$1"
if [ ! -f "$1" ]
then
echo "File $1 does not exist."
exit 1
fi
echo "File exists!"
and in the same directory, I have a data folder containing stuff.txt.
If I run ./test.sh data/stuff.txt I see the expected output:
arg1=data/stuff.txt
"File exists!"
However, if I call this script from a second script test2.sh, in the same directory, like:
#!/bin/bash
fn="data/stuff.txt"
./test.sh $fn
I get the mangled output:
arg1=data/stuff.txt
does not exist
Why does the call work when I run it manually from a terminal, but not when I run it through another Bash script, even though both are receiving the same file path? What am I doing wrong?
Edit: The filename does not have spaces. Both scripts are executable. I'm running this on Ubuntu 18.04.
The filename was getting an extra whitespace character added to it as a result of how I was retrieving it in my second script. I didn't note this in my question, but I was retrieving the filename from folder list over SSH, like:
fn=$(ssh -t "cd /project/; ls -t data | head -n1" | head -n1)
Essentially, I wanted to get the filename of the most recent file in a directory on a remote server. Apparently, head includes the trailing newline character. I fixed it by changing it to:
fn=$(ssh -t "cd /project/; ls -t data | head -n1" | head -n1 | tr -d '\n' | tr -d '\r')
Thanks to #bigdataolddriver for hinting at the problem likely being an extra character.

How to pass a file name to sed|grep|awk command inside a variable assignment in unix

Im trying to execute the following script to get the currentpath string from a file and pass it to find and replace in the next command. it works fine when running directly in the host server , but when tried to execute from jenkins build step, i'm getting a failure that file not found.
Error: sed: can't read test.txt: No such file or directory
Expected result is to get the "test.txt" file updated with "newPath" wherever the "currentPath" exists
code :
user="testuser"
host="remotehost"
newPath="/testpath/"
filetoUpdate="./test.txt" # this is a file
ssh -o UserKnownHostsFile=/dev/null -o StrictHostKeyChecking=no -i ~/.ssh/id_rsa ${user}#${host} "currentPath="$(sed -n '/^PATH='/p $filetoUpdate | cut -d'=' -f2)" ; echo "currentPath was "$currentPath"" ; sed -n 's|$currentPath|$newPath|g' $filetoUpdate"
One of the problems is that locally defined variables newPath and filetoUpdate will not be available in script running on remote host. Also in this script only currentPath= will be executed on remote host, rest of the commands run locally.
I'd recommend to save script in a separate file.
test.sh:
newPath="/testpath/"
filetoUpdate="./test.txt"
currentPath=`sed -n '/^PATH=/p' $filetoUpdate | cut -d= -f2`
echo "currentPath was "$currentPath""
sed -i .bak "s|$currentPath|$newPath|g" $filetoUpdate
(I added -i for in-site editing)
And to run it with the command
ssh remotehost < t.sh

Why is this bash script not changing path?

I wrote a basic script which changes the directory to a specific path and shows the list of folders, but my script shows the list of files of the current folder where my script lies instead of which I specify in script.
Here is my script:
#!/bin/bash
v1="$(ls -l | awk '/^-/{ print $NF }' | rev | cut -d "_" -f2 | rev)"
v2=/home/PS212-28695/logs/
cd $v2 && echo $v1
Does any one knows what I am doing wrong?
Your current script makes no sense really. v1 variable is NOT a command to execute as you expect, but due to $() syntax it is in fact output of ls -t at the moment of assignment and that's why you have files from current directory there as this is your working directory at that particular moment. So you should rather be doing ordinary
ls -t /home/PS212-28695/logs/
EDIT
it runs but what if i need to store the ls -t output to variable
Then this is same syntax you already had, but with proper arguments:
v1=$(ls -t /home/PS212-28695/logs/)
echo ${v1}
If for any reason you want to cd then you have to do that prior setting v1 for the same reason I explained above.

Custom unix command combination assigning to variable

I want to make UNIX script, which will automatically move my working directory files to newly created directories.
Example: In you dir you got files:
001-file.html,
001-file.rb,
002-file.html,
002-file.rb
And 2 files will be moved to ./NewDir/001-file and another 2 to ./NewDir/002-file
My problem is that after I get correct string from Unix commands I cannot assign it to variable.
Here is my code:
clear
echo "Starting script"
echo "Dir = "$(pwd)
read -p "Please enter count(max '999') of different file groups:" max_i
read -p "Enter new dir name:" outer_dir_name
for ((i=0; i<=$max_i;i++)) do
a1=$(($i/100))
a2=$((($i-$a1*100)/10))
a3=$(($i-($a2*10)-($a1*100)))
inner_dir_name=$((ls *[$a1][$a2][$a3]* 2>/dev/null | head -n 1 | cut -f1 -d"."))
echo $inner_dir_name
echo "--------------"
done
One pair of round parentheses is enough for command substitution.
inner_dir_name=$(ls *[$a1][$a2][$a3]* 2>/dev/null | head -n 1 | cut -f1 -d".")
It looks like you're going about the operation the hard way. I would probably do something like this, assuming that there are no spaces in the file names:
ls | sed 's/\..*$//' | sort -u |
while read prefix
do
mkdir -p $outer_dir_name/$prefix
mv $prefix.* $outer_dir_name/$prefix
done
The ls could be made more precise with:
ls [0-9][0-9][0-9]-file.*
If I was worried about blanks and other odd-ball characters in the file names, I'd have to use something more careful:
for file in [0-9][0-9][0-9]-file.*
do
prefix=${file%%.*}
[ -d "$outer_dir_name/$prefix" ] || mkdir -p "$outer_dir_name/$prefix"
mv "$file" "$outer_dir_name/$prefix"
done
This executes more mv commands, in general.

Why is grep displaying command as part of output?

I have written a bash script that finds any executable files in our scripts directory, then performs a grep on the resulting files to display a description, if it was included in the file.
A "description" is identified in each file as a line beginning with "# DESC:"
For some reason, the script also includes the grep command that is being run (but only once). Does anyone know why this is?
Script and output shown below. Why does the second line in the output happen?
Script
#!/bin/bash
# Find any FILES that are EXECUTABLE in the SCRIPTS
# directory and display any description, if there is one
find /opt/scripts/. -perm -111 -type f -maxdepth 1 | while read line ;
do
file=$(basename "$line")
printf "\033[1m%10s\033[0m : " $file
grep "# DESC:" "$line" | cut -c 9-
done
Output
desc : Displays all the scripts and their descriptions
DESC:" "$line" | cut -c 9-
showhelp : Displays the script help file
test : Script to perform system testing
Reason
Presumably your grepping script is also in /opt/scripts?
So it finds itself, and finds the grep subject '#DESC' and prints that.
You could fix that by adding a # DESC line to the top of your grep script, and just outputting the first result found by each grep using 'grep -m1'
grep -m1 '# DESC' "$line" | cut -c 9-
<humour>Otherwise its just turtles all the way down... ;-) </humour>
Alternative Fix
You could also improve the grep by using a regular expression and anchoring to the beginning of the line:
egrep -m1 '^# DESC' "$line" | cut -c 9-

Resources