Bash Merge 2 files conditionally - bash

I'm trying to merge the second field of the csv with all the id's in the diff file. codes.csv has 2 fields: ID,Description. I keep getting an error on the second cat.
cat: codes.cvs: No such file or directory.
The file does exist and I'm running the script from the same directory as codes.csv.
for i in `cat diff.txt`;
do
for j in `cat codes.cvs`;
do
id = `sed "$j"`;
desc = `sed "?=$j"`;
if [$i == $id]
then
echo "$id $desc"
fi
done;
done;
Any ideas what I am doing wrong here?

Looks like a simple typo. codes.cvs should be codes.csv as you indicated the name was everywhere else.
for i in `cat diff.txt`;
do
for j in `cat codes.csv`;
do
id=`sed "$j"`;
desc=`sed "?=$j"`;
if [ $i == $id ]
then
echo "$id $desc"
fi
done;
done;

Related

how to edit this code to show multiple files (it currently works with 1 file)?

I have created a shell script in order to find 2 files. While it works with 1 it does not work with 2 or multiple. Any help?
#!/bin/bash
FILENAME="abc"
if [ -f "${FILENAME}"* ]
then
echo "EXISTS"
else
echo "NOT EXISTS"
fi
Expected: EXISTS
Error:
./test.sh: line 5: [: abc1.sh: binary operator expected
NOT EXISTS
Error is here:
if [ -f "${FILENAME}"* ]
-f option accepts a single file. If there are more files that start
with $FILENAME then * is expanded and more than one file is passed
to -f. It's also reported by shellcheck:
$ ~/.cabal/bin/shellcheck test.sh
In test.sh line 5:
if [ -f "${FILENAME}"* ]
^-- SC2144: -f doesn't work with globs. Use a for loop.
If you want to check if there is at least one file that starts with
$FILENAME without using external tools such as find you need use
for loop like that:
#!/bin/bash
FILENAME="abc"
for file in "${FILENAME}"*
do
if [ -f "$file" ]
then
echo File exists
exit 0
fi
done
echo File does not exist.
exit 1
The simple way is to check if there less then 2 files with same name abc*:
#!/bin/bash
FILENAME="abc"
COUNT_FILES=$(find . -maxdepth 1 -name "$FILENAME*" -type f | wc -l)
if [[ $COUNT_FILES -lt 2 ]]
then
echo "NOT EXISTS"
else
echo "EXISTS"
fi
if ls /path/to/your/files* 1> /dev/null 2>&1
then
echo "files do exist"
else
echo "files do not exist"
fi
This is what I was looking for. What I wanted was a function that looks for single OR multiple files, which the code above performed perfectly. Thanks for the previous answers, much help.

how to create incremental files with version in shell

how to create files dynamically when i run shell script.
Intially in the /tmp folder i need to check if file like(CFT_AH-120_v1.txt) exist in tmp folder else create CFT_AH-120_v1.txt. Next time when i run shell script it should create CFT_AH-120_v2.txt and in each run it should increment the version number of the file.
In tmp folder i should have files like
CFT_AH-120_v1.txt
CFT_AH-120_v2.txt
CFT_AH-120_v3.txt
i will get CFT_AH-120 from variable dynamically.
#!/bin/bash
export filename
temp=$(find CFT_AH-120-V* | sort -V | tail -1)
if [ -e $temp ]
then echo "ok"
echo $temp
fname="${temp%.*}"
echo $fname
temp1="${temp%[[:digit:]]*}$((${temp##*[[:alpha:]]} + 1))"
echo $temp1
touch $temp1 ".txt"
else
touch CFT_AH-120-V1.txt
echo "nok"
fi
I am not sure the exact requirement for you. As per my understanding this is a simple way of approach.
#!/bin/bash
file_temp=$(find . -name "CFT_AH-120-V*" -type f | sort -V | tail -1)
echo $temp
if [ -z "$temp" ]; then
echo "File not found!"
else
num_temp=$(echo $temp | cut -d '-' -f3- | sed 's/V//')
num_value_incr=$(expr $new_temp + 1)
touch "CFT_AH-120-V$num_value_incr"
echo "New file created!"
fi
Note: This code search for the largest value of the "V"....number.... (eg.***V120) and increment based on that value and also the intermediate number wont be increment. If you need the missing numbers to be created, then the logic for this code needs to be changed.
Hope this might help you!

Shell script to check a log file and print the errors that are found in it

I am pretty new to shell scripting . I am trying to write a script to check for logfile for errors (error strings are hardcoded), and i have to print the lines containing the error . i am able to write the logic but need pointers to read a file from user input.
Appreciate the help thanks.
Logic:
Accept the logfile patch from user
Check if the logfile is present or not
If present search the file for lines containing the error string (eg. Error, ORA)
Print the lines containing error strings , also write the output to a logfile
Read the log file from user
Set error strings
search="ERROR"
set a path for output file
outfile="file1.txt"
Execution logic
find "$mydir" -type f -name "$filename" |while read file
do
RESULT=$(grep "$search" "$file")
if [[ ! -z $RESULT ]]
then
echo "Error(s) in $file: $RESULT" >> "$outfile"
fi
done
I'm not sure what you mean with "need pointers to read a file from user input". I assume "pointers" are script arguments.
You can use this script:
#!/bin/bash
expected=outfile
for f in $#
do
if [ "$expected" = outfile ]; then
OUTFILE=$1
expected=search
elif [ "$expected" = search ]; then
SEARCH=$2
expected=files
elif [[ -f $f ]]; then
RESULT=`grep "$SEARCH" $f`
if [ -n "$RESULT" ]; then
echo -e "\n"
echo "Error(s) in "$f":"
echo $RESULT
echo -e "\n" >> $OUTFILE
echo "Error(s) in "$f":" >> $OUTFILE
echo $RESULT >> $OUTFILE
fi
fi
done
Invoke with:
scriptname outfile search files
where:
scriptname: is the name of file containing the script.
outfile: the name of the output file
search: the text to be searched
files: one or many file name or file patterns.
Examples (I assume the name of the script is searcherror and it is in the system path):
searcherror errorsfound.txt primary /var/log/*.log
searcherror moreerrors.txt "ORA-06502" file1.log /var/log/*.log ./mylogs/*

Variables empty after inner loop

i have an issue with my bash script
t='Hostname\cfg;'
echo "Header" > $DST
for i in *
do
t="$i;"
egrep -v "(^$|^#)" $IPLIST | while read ii
do
if grep -q "$ii" $i
then
t=$t"y;"
else
t=$t"n;"
fi
echo "$t"
done
echo "x$t"
n=$(($n + 1))
echo "$n"
#echo "$ii;$t" # >> $DST
#t=""
done
Produces the following output:
h0010001.conf;y;
h0010001.conf;y;y;
<ommited>
h0010001.conf;y;y;y;y;y;y;y;y;y;y;y;y;y;y;y;y;y;y;y;y;n;n;y;y;y;y;y;y;y;y;y;y;y;y;n;y;y;y;y;y;y;n;y;y;y;y;y;y;y;y;y;n;n;
xh0010001.conf;
So for some reason the t Variable is empty after the inner loop has completed.
What I want to achieve is, to write t - after the second loop into a file.
#Barmar was spot on. Here's a typical workaround.
Change the while loop to run in the parent shell:
while read ii
do
if grep -q "$ii" $i
then
t=$t"y;"
else
t=$t"n;"
fi
echo "$t"
done < <(egrep -v "(^$|^#)" $IPLIST)

bash script prova.sh: line 76: syntax error: unexpected end of file

I have below script but I can't find the error. Somebody an help me ?
In concrete I split a big file in different then compress any file, move it and send by ftp rename destination filename.
Something not work :(
in line:
put ${file} ${7}.T${j}(+1)
I try to rename the file with (+1) ended new filename
Kind regards
#!/bin/bash
# configuration stuff
# ${1} absolute path file
# ${2} num_files
# ${3} output_filename
# ${4} ipMainframe ip to put files
# ${5} FTP username
# ${6} FTP password
# ${7} destination filename
if [ ! $# == 7 ]; then
#number of parameter different of two
echo "Number of parameter incorrect"
echo "Command use: LLP_split_gzip_sendFTPandTrigger.sh absolute_path_file number_of_pieces output_filename ipMainframe userFTP pwdFTP destinationFilename"
exit 1
fi
if [ -f ${1} ]; then
# If file exists
if [[ ${2} =~ ^[\-0-9]+$ ]] && (( ${2} > 0)); then
# if number of pieces is an integer > 0
#Remove old files
echo "home directory = $HOME"
CMD=`rm -f '"$HOME"/"$3"*'`
if [ $? != 0 ]; then
echo "Impossible to remove old files $home/llp_tmp* $home/"$3"* in home directory"
echo $CMD
fi
# Calculate line for every file splitted
total_lines=$(cat ${1} | wc -l)
((lines_per_file = (total_lines + ${2} - 1) / ${2}))
# Split the actual file, maintaining lines.
CMD=`split -l "$lines_per_file" "$1" "$HOME"/llp_tmp`
if [ $? != 0 ]; then
echo "SPLITTING FILE ERROR: problem to split file."
echo $CMD
exit 3
fi
#For every file splitted rename and zip it
i=1
for file in $HOME/llp_tmp*; do
CMD=`mv "$file" "$3"."$i"`
if [ $? != 0 ]; then
echo "Impossible to rename file"
echo $CMD
exit 5
fi
CMD=`gzip "$3"."$i"`
if [ $? != 0 ]; then
echo "Impossible to compress file $3.$i"
echo $CMD
exit 6
fi
i=`expr $i + 1`
done
ftp -n ${4} << EOF
j=1
user ${5} ${6}
for file in $3.*; do
put ${file} ${7}.T${j}(+1)
j=`expr $j + 1`
done
quit
else
echo "number of pieces second parameter must be more than 0."
exit 2
fi
else
echo "absolute path first paramater doesnt exist"
exit 1
fi
exit 0
You are not terminating your here document. When I run your script I get:
gash.sh: line 72: warning: here-document at line 54 delimited by end-of-file (wanted `EOF')
gash.sh: line 73: syntax error: unexpected end of file
ftp -n ${4} << EOF is the issue. Where is your here document?
The warning says it all, you don't have an EOF marker. Note that this MUST NOT BE INDENTED! The EOF must be in "column 0" and have no trailing characters, including whitespace.
Edit: It appears you want to use program constructs within a single FTP session - I don't know of a way of doing that in Bash. Perl has an easy to use FTP module where you can do it, simple example:
use strict;
use Net::FTP;
my $ftp = Net::FTP->new ("hostname");
$ftp->login ("username", "password");
$ftp->binary ();
for my $file (glob("$ENV{HOME}/llp_tmp*")) {
$ftp->put ($file);
}
$ftp->quit();
You don't need parentheses around +1.
Change it to:
put "${file}" "${7}.T${j}+1"
It's good practice to quote variables.
Another tip: Instead of j=`expr $j + 1`, you can simply use ((j++)).

Resources