How to apply cut and sed commands to Powershell? - bash

I have a bash script which retrieves data from 2 separate files (1 for user data and another for default text) and outputs a circular letter:
if [ $# -eq 0 ]
then
echo "Please enter two parameters"
exit
elif [ $# -eq 1 ]
then
echo "Please enter one more parameter"
exit
elif [ $# -gt 2 ]
then
echo "Please enter ONLY two parameters"
exit
fi
while read line
do
iN=`echo $line | cut -f1 -d";"`
iA=`echo $line | cut -f2 -d";"`
iD=`echo $line | cut -f3 -d";"`
cat $2|sed "s/<NAME>/$iN/g" | sed "s/<ADDRESS>/iA/g" | sed "s/<DATE>/$iD/g"
done < data
It needs to be converted to a PS script, here's what I could've done so far:
if ($# -eq 0) {
Write-Output "Please enter two parameters"
} elseif ($# -eq 1 ) {
Write-Output "Please enter one more parameter"
} elseif ($# -gt 2) {
Write-Output "Please enter ONLY two parameters"
}
foreach($line in Get-Content .\data.txt) {
}
I wasn't able to find any equivalent of sed or cut commands on the internet so I'd appreciate any kind of help.

You can use Unix Utils for Windows set that has all these commands converted, and we have been using them for a long time in production with no issues.
https://sourceforge.net/projects/unxutils/
It has most of them: sed, cut, cat etc.

Related

Strange syntax error in if condition - Shell Script

So I'm making a shell script in Ubuntu. It's purpose is simple. You give a command with arguments and you get a different operation each time. The problem is that when I run the the script it won't actually run because of a syntax error in one elif. The most suspicious thing is that I have a similar elif above wich works or at least doesn't pop a syntax error...
I'm leaving my code for you to see it and understand. Thanks in advance!
if [ "$1" = "-a" -a $# -lt 3 ]
then
echo "Add a new line in katalogos!"
read -p "Give me a name... " name
read -p "Give me a surname... " surname
read -p "Give me a city name... " cityName
read -p "Give me a phone number... " num
echo "$name $surname $cityName $num" > katalogos
elif [ "$1" = "-l" -a $# -lt 3 ]
then
echo "Content of katalogos will be sorted numerically and blank lines will be excluded!"
sort -b -n katalogos
elif [ "$1" = "-s" -a $# -lt 4 ]
if [[ $2 != *[!0-9]* ]]
then
echo "Content of katalogos will be sorted according to the second argument!"
sort +$3 katalogos
fi
elif [ "$1" = "-c" -a $# -lt 4 ] // syntax error
if [[ $2 = *[!0-9]* ]]
then
echo "Content of katalogos will be sorted according to the keyword!"
if [ $(grep -e "$2" katalogos | wc -l) -eq 0 ]
then
echo "String is not matched."
else
grep -e "$2" katalogos
fi
fi
elif [ "$1" = "-d" -a ( "$3" = "-b" -o "$3" = "-r" ) ]
if [[ $2 = *[!0-9]* ]]
then
echo "Katalogos's string matching lines will be deleted and blank lines will be in their place, assuming that the third argument equals -b, else just the lines will be deleted!"
if [ $(grep -e $2 katalogos | wc -l) -eq 0 ]
then
echo "String is not matched."
else
if [ "$3" = "-b" ]
then
sed -i "$3" katalogos | sed -i '$ a '
echo "A blank line inserted in place of the deleted one."
else
sed -i "$3" katalogos
echo "Line deleted."
fi
fi
fi
elif [ "$1" = "-n" ]
echo "katalogos's number of blank lines will be shown with the ability to delete them!"
grep -cvP '\S' katalogos
read -p "Do you want to delete them? Type 1 for yes or 0 for no... " ans
if [ $ans -eq 1 ]
then
grep -cvP '\S' file | sed -i
echo "Lines deleted."
fi
else
echo "Help centre!"
echo "-Type ./telcat -a to insert a new line to katalogos."
echo "-Type ./telcat -l to see the contents of katalogos sorted numerically (excluding blank lines)."
echo "-Type ./telcat -s plus a number to see the contents of katalogos sorted by the data that the number points to."
echo "-Type ./telcat -c plus a keyword to see only the lines that match with the word given."
echo "-Type ./telcat -d plus a keyword and -b or -r to delete the lines that contain the word given. Specifically if the third argument is -b it will automatically add a blank line to the deleted one and if it is -r it will not."
echo "-Type ./telcat -n to see the number of blank lines of katalogos."
echo "End of help centre!"
fi

Combine two Bash while loop statements

I am trying to combine 2 different logical statements in a single while loop, but having trouble getting the logic correct so that 2 different checks can be evaluated in the same loop. For example, I have the following 2 logical statements.
Logic 1
Determine if the entered username is blank and if it is ask the user to re-enter a different username.
echo -ne "User Name [uid]$blue:$reset "
read USERNAME
USERNAME=$(echo "$USERNAME" | tr "[:upper:]" "[:lower:]")
while [[ -z "$USERNAME" ]]; do
echo ""
printf "%s\n" "The User Name CAN NOT be blank"
echo ""
echo -ne "User Name [uid]$blue:$reset "
read USERNAME;
USERNAME=$(echo "$USERNAME" | tr "[:upper:]" "[:lower:]")
done
Logic 2
Determine if the read username already exists and if it does ask the user to re-enter a username.
echo -ne "User Name [uid]$blue:$reset "
read USERNAME
USERNAME=$(echo "$USERNAME" | tr "[:upper:]" "[:lower:]")
$(command -v getent) passwd "$USERNAME" &>/dev/null
while [[ $? -eq 0 ]]; do
echo ""
printf "%s\n" "$USERNAME exists in LDAP"
echo ""
echo -ne "User Name [uid]$blue:$reset "
read USERNAME;
USERNAME=$(echo "$USERNAME" | tr "[:upper:]" "[:lower:]")
$(command -v getent) passwd "$USERNAME" &>/dev/null
done
For achieving the described goal I have tried while loops and nested if statements and am just confused at this point. Basically as part of the script I would like these 2 logical statements to be combined when the user is asked to enter a username without the script exiting until a valid value is entered.
Don't use uppercase variable names!
#!/bin/bash
while true; do
echo -ne "User Name [uid]$blue:$reset "
read username
[ -z "$username" ] && echo -e "\nThe User Name CAN NOT be blank\n" && continue
username=$(tr [:upper:] [:lower:] <<< $username)
[ -z $(getent passwd "$username") ] && break || echo -e "\n$username exists in LDAP\n"
done
You could move the conditional check from the while statement to a pair of if statements. In this case, I've also moved the read and related commands to the top of the loop. This means you don't need extra read commands before the loop.
#!/bin/bash
while true; do
echo -ne "User Name [uid]$blue:$reset "
read username;
username=$(echo "$username" | tr "[:upper:]" "[:lower:]")
$(command -v getent) passwd "$username" &>/dev/null
if [[ -z "$username" ]]; then
echo ""
printf "%s\n" "The User Name CAN NOT be blank"
echo ""
continue #Skips the rest of the loop and starts again from the top.
fi
if [[ $? -eq 0 ]]; then
echo ""
printf "%s\n" "$username exists in LDAP"
echo ""
continue #Skips the rest of the loop and starts again from the top.
fi
#If execution reaches this point, both above checks have been passed
break #exit while loop, since we've got a valid username
done
As an aside, it's often recommended to avoid uppercase variable names, in order to avoid conflicts with system environment variables.

Shell Script improvement for getting diff result

I have shell Script written which does a job of comparing two files and and gives me result in a HTML format for defects. But i want to improve it so that i can only get modified files defects instead of legacy defects also. I am using this script to get Coverity report.
while read line; do
n=$((++n))
if echo $line | grep '^[[:space:]]*>' &>/dev/null; then
if [ $(($n % 2)) -eq 1 ]; then
# TODO somehow get proper defect number from html
# echo "Defect num: $(($n/2 + 1))"
def_num=$((++def_num))
fi
echo $line | sed -n -e 's/>[[:space:]]*\(.*\)/\1/p'
if [ $(($n % 2)) -eq 0 ]; then
echo "-------------------------------"
fi
done < <(diff -y -W 200 ./cov-results-base/result.filt ./cov-results-changed/result.filt)
echo "==============================="
echo
echo "Number of defects in old code: $(tac cov-results-base/summary.xml |
sed -n '/num/{s|<num>\(.*\)</num>|\1|p; q;}')"
echo "Number of defects in new code: $(tac cov-results-changed/summary.xml |
sed -n '/num/{s|<num>\(.*\)</num>|\1|p; q;}')"
This enables you to get the last modification time of a file and the compare with the current time.
now=`date +%s`
modified=`stat -c "%Y" $file`
if [ $(($now-$modified)) -gt 0 ]; then
echo "not modified";
else
echo "modified";
fi
I hope that this is what you wanted.

Unix : Integer expression expected

#!/bin/bash
location=$1
englishCount=0
bourneCount=0
CShellCount=0
symbolicCount=0
emptyCount=0
dirCount=0
if [ ! $# -eq 1 ]; then
echo Need to supply one argument
exit
fi
if [ ! -d $1 ]; then
echo Directory not found
exit
fi
find $location | while read item
do
if [-f "$item" ]
then
if [ "file $loc/* | grep English | wc -l" -eq 1 ]
then
$englishCount=$[englishCount+1]
elif [ "file $loc/* | grep Bourne | wc -l" -eq 1 ]
then
$bourneCount=$[bourneCount+1]
elif [ "file $loc/* | grep C.Shell | wc -l" -eq 1 ]
then
$CShellCount=$[$CShellCount+1]
elif [ "file $loc/* | grep symbolic | wc -l" -eq 1 ]
then
$symbolicCount=$[$symbolicCount+1 ]
elif
$emptyCount=$[$emptyCount+1 ]
elif [ -d "$item" ]
then
dirCount=$[dirCount+1]
fi
done
echo "English count: " $englishCount
echo "bourne count: " $bourneCount
echo "CShell count: " $CShellCount
echo "symbolic count : " $symbolicCount
echo "empty count: " $emptyCount
echo "Directory count: " $dirCount
I'm trying to create a script to sort the contents of a directory by type but, I get an error saying that Integer expression expected. IM under the impression that the expression used to compare to the integer one would result in a numeric value but, my script does not recognize it as such.
In the line
if [ "file $loc/* | grep English | wc -l" -eq 1 ]
You are comparing a string with a number. Instead try
if [ `file $loc/* | grep English | wc -l` -eq 1 ]
The back ticks cause "the thing between them" to be run as a subprocess, with the result returned to this program. And then the "string" that is returned (some numeric output from wc -l ) is turned into an integer and compared with 1.
Obviously you have do to this to all similar instances.

Bash Function Components Working Independently but Not Together

I have a bash script that has this function in it:
function start_vi()
{
echo "Please enter a file name with complete path to open in vi:"
read input_file
if [ -d "$input_file" ]
then
echo "You entered a directory."
echo "Please try again and enter a readable/writable file."
fi
grep_var="file $input_file | grep -c data"
if [ $? -eq 0 ]
then
vi $input_file
else
echo "File not found or invalid file type. Please try again."
fi
}
For the most part the function works fine. My problem is that the two if statements work fine independently, eg, if I comment out one of them, the test works and it does what I want. But together, as written, for example, when I type in a directory at the prompt, vi opens it as a file, where the test should return an echo saying that it's a directory, as it does when functioning alone.
Any ideas on why this is? I'm still relatively new at bash scripting so it is probably easy for the pros, but I have been banging my head against the wall for a while now.
Thanks in advance.
Add a return statement in the first if/then:
function start_vi()
{
echo "Please enter a file name with complete path to open in vi:"
read input_file
if [ -d "$input_file" ]
then
echo "You entered a directory."
echo "Please try again and enter a readable/writable file."
return
fi
grep_var="file $input_file | grep -c data"
if [ $? -eq 0 ]
then
vi $input_file
else
echo "File not found or invalid file type. Please try again."
fi
}
Otherwise, it will print and then open the file anyway, as your second test should be like this:
file $input_file | grep -c data
if [ $? -eq 0 ]
The $? is the exit code of the last run command. Assigning to a variable (i.e. grep_var="...") sets $? to 0. What you seem to have wanted is the exit code of grep -c data - in that case, use backticks ` instead of quotes " to run commands, like below. Or you can write it like this:
grep_var=`file $input_file | grep -c data`
if [ $grep_var != 0 ]
to compare the string value (i.e. what grep -c data returns - the count of data lines).
Doing some of the above should solve the problem.
You need a loop
function start_vi()
{
echo "Please enter a file name with complete path to open in vi:"
read input_file
while [ -d "$input_file" ]
do
echo "You entered a directory."
echo "Please try again and enter a readable/writable file."
read input_file
done
grep_var="file $input_file | grep -c data"
if [ $? -eq 0 ]
then
vi $input_file
else
echo "File not found or invalid file type. Please try again."
fi
}
All you need is a loop:
....
read input_file
while [ ! -f "$input_file" ]
do
echo "You did not enter a file"
echo "Please try again and enter a readable/writable file."
read input_file
done
grep_var="file $input_file | grep -c data"
if [ $? -eq 0 ]
then
vi $input_file
else
echo "File not found or invalid file type. Please try again."
fi
I think this may be closer to what you want to do..
function start_vi()
{
echo "Please enter a file name with complete path to open in vi:"
read input_file
grep_var=`file $input_file 2>&1 | grep -c data`
while [ $? -ne 0 ]
do
echo "File not found or invalid file type. Please try again."
read input_file
grep_var=`file $input_file 2>&1 | grep -c data`
done
vi $input_file
}

Resources