LinuxQuestions.org
Download your favorite Linux distribution at LQ ISO.
Go Back   LinuxQuestions.org > Forums > Non-*NIX Forums > Programming
User Name
Password
Programming This forum is for all programming questions.
The question does not have to be directly related to Linux and any language is fair game.

Notices


Reply
  Search this Thread
Old 06-22-2011, 05:32 AM   #1
confusiac437
LQ Newbie
 
Registered: Jun 2011
Posts: 3

Rep: Reputation: Disabled
Need File Name comparison help on Korn Shell Script


I am trying to compare two filenames including the paths. Basically if two paths are similar then my program wants to display message. So I need to check for if two pathnames are same in the sorce and destination. So I was trying for the code to compare tow filename sincluding "\" and if the Parent FIle Path is found in the child file path then I need to displays ome message. I was trying to modify something like this:
#!/bin/ksh
# Sample script

file1="C:\Text\Latest\Article\News.txt"

file2="C:\Text\Latest"

pattern1=$file2

if [[ $file1 = pattern1* ]]
then
echo "Do something"
fi

========================================
Also tried == and $file2 in place of pattern1.

Last edited by confusiac437; 06-22-2011 at 05:33 AM. Reason: Spelling Mistake
 
Old 06-22-2011, 05:54 AM   #2
colucix
LQ Guru
 
Registered: Sep 2003
Location: Bologna
Distribution: CentOS 6.5 OpenSuSE 12.3
Posts: 10,509

Rep: Reputation: 1983Reputation: 1983Reputation: 1983Reputation: 1983Reputation: 1983Reputation: 1983Reputation: 1983Reputation: 1983Reputation: 1983Reputation: 1983Reputation: 1983
You might try the regular expression match operator:
Code:
#!/bin/ksh
file1="C:\Text\Latest\Article\News.txt"
file2="C:\Text\Latest"

if [[ $file1 =~ $file2 ]]
then
  echo "Do something"
fi
Anyway the backslashes in the file names may confuse the shell which interprets them as escape characters. For this reason it is convenient to change them into a slash or some other character to do the comparison:
Code:
#!/bin/ksh
file1="C:\Text\Latest\Article\News.txt"
file2="C:\Text\Latest"

if [[ ${file1//\\//} =~ ${file2//\\//} ]]
then
  echo "Do something"
fi
Hope this helps.
 
1 members found this post helpful.
Old 06-22-2011, 06:46 AM   #3
grail
LQ Guru
 
Registered: Sep 2009
Location: Perth
Distribution: Manjaro
Posts: 9,999

Rep: Reputation: 3190Reputation: 3190Reputation: 3190Reputation: 3190Reputation: 3190Reputation: 3190Reputation: 3190Reputation: 3190Reputation: 3190Reputation: 3190Reputation: 3190
Well I am not sure why you have copied file2 into pattern1, but ultimately you only made 2 small typos to get your script to work as is:
Code:
#!/bin/ksh
# Sample script

file1="C:\Text\Latest\Article\News.txt"

file2="C:\Text\Latest"

pattern1=$file2

if [[ $file1 = "$pattern1"* ]]
then
    echo "Do something"
fi
 
1 members found this post helpful.
Old 06-28-2011, 12:16 PM   #4
confusiac437
LQ Newbie
 
Registered: Jun 2011
Posts: 3

Original Poster
Rep: Reputation: Disabled
Need More Clarification

The approaches suggested do help. But I am trying something like:

##Logic
#Need to copy from one file-path to other file-path
#e.g. from D:\Books\Latest\Novels\Finkler to D:\Books\Latest
#The two string approach would give match even if the destination is only D:\.
#So introduced third string str (which is constant) to check for match with str2 first
#Then compare the fixed path in str3 with str

#! /bin/ksh
str=$1
str2=$2
str3="D:\Books\Latest"
echo $str
echo $str2
if [[ $str2 == [$str3]* ]] then
if [[ $str == [$str2]* ]] then
echo "Go"
else
echo "NoGo1"
fi
else
if [[ $str == [$str3]* ]] then
echo "Go2"
else
echo "NoGo2"
fi
fi

The above code gives me NoGo2 even for matching string.
I am entering arguments as:
D:\Books\Latest D:\Books\Latest\Novels\Finkler
 
Old 06-29-2011, 12:09 AM   #5
grail
LQ Guru
 
Registered: Sep 2009
Location: Perth
Distribution: Manjaro
Posts: 9,999

Rep: Reputation: 3190Reputation: 3190Reputation: 3190Reputation: 3190Reputation: 3190Reputation: 3190Reputation: 3190Reputation: 3190Reputation: 3190Reputation: 3190Reputation: 3190
So we should have mentioned before, please use [code][/code] tags to make your code more readable and indented.

As for your code:

1. Make sure arguments are passed to script with single quotes around them to preserve the \ and not allow escaping of next character

2. str3 is same as above and needs single quotes

3. Replace [] around comparisons, ie [$str3]*, with "" as I explained in previous post, ie "$str3"*

4. Without any of the changes above your script fails anyway due to missing semi-colon before each of your 'then' statements

Once these changes are made the result I get is: NoGo1, which appears to be correct based on input.
 
Old 06-29-2011, 01:47 AM   #6
Nominal Animal
Senior Member
 
Registered: Dec 2010
Location: Finland
Distribution: Xubuntu, CentOS, LFS
Posts: 1,723
Blog Entries: 3

Rep: Reputation: 948Reputation: 948Reputation: 948Reputation: 948Reputation: 948Reputation: 948Reputation: 948Reputation: 948
Quote:
Originally Posted by confusiac437 View Post
I am trying to compare two filenames including the paths. Basically if two paths are similar then my program wants to display message.
What do you mean by "are similar"?

If you want to test if string $file1 starts with $file2 or vice versa, use
Code:
if [ "${file1:0:${#file2}}" == "${file2:0:${#file1}}" ]; then
    echo "$file1 starts $file2, or $file2 starts $file1."
fi
If you want the comparison to be case insensitive, use
Code:
typeset -u temp1 temp2
temp1="${file1:0:${#file2}}"
temp2="${file2:0:${#file1}}"
if [ "$temp1" == "$temp2" ]; then
    echo "($file1 prefix) ${file1:0:${#temp1}} and ($file2 prefix) ${file2:0:${#temp}} match."
fi
If you want to find the longest common path prefix, it gets a bit more complicated; especially if you wish to handle symlinks and bind-mounts correctly.
 
1 members found this post helpful.
Old 07-01-2011, 10:15 AM   #7
confusiac437
LQ Newbie
 
Registered: Jun 2011
Posts: 3

Original Poster
Rep: Reputation: Disabled
Unhappy Any alternate approaches

Code:
if [ "${file1:0:${#file2}}" == "${file2:0:${#file1}}" ]; then
    echo "$file1 starts $file2, or $file2 starts $file1."
fi
If you want the comparison to be case insensitive, use
Code:
typeset -u temp1 temp2
temp1="${file1:0:${#file2}}"
temp2="${file2:0:${#file1}}"
if [ "$temp1" == "$temp2" ]; then
    echo "($file1 prefix) ${file1:0:${#temp1}} and ($file2 prefix) ${file2:0:${#temp}} match."
fi

The above approach does not work for me. Am working in Korn Shell on very old version of Unix.What are the other alternatives in case I basically just want to check if one file path contains other file path in it?
 
Old 07-01-2011, 02:14 PM   #8
Nominal Animal
Senior Member
 
Registered: Dec 2010
Location: Finland
Distribution: Xubuntu, CentOS, LFS
Posts: 1,723
Blog Entries: 3

Rep: Reputation: 948Reputation: 948Reputation: 948Reputation: 948Reputation: 948Reputation: 948Reputation: 948Reputation: 948
Well, I have access to ksh on SunOS 5.10, and for it, case seems to work well:
Code:
FILE1="/path/to/some/file"
FILE2="/path/to"

# +u case sensitive, -u is case insensitive
typeset +u TEMP1 TEMP2
TEMP1="$FILE1"
TEMP2="$FILE2"

case "$TEMP1" in
  "$TEMP2")       echo "FILE1 ($FILE1) is the same as FILE2 ($FILE2)" ;;
  "${TEMP2%/}/"*) echo "FILE1 ($FILE1) has prefix FILE2 ($FILE2)" ;;
esac
case "$TEMP2" in
  "${TEMP1%/}/"*) echo "FILE2 ($FILE2) has prefix FILE1 ($FILE1)" ;;
esac
Note that the above uses ${TEMP%/}/ which literally means the value of TEMP, with the trailing slash removed if there is one, with a trailing slash added. Even old Korn shells should support that expression. (I recommend you check, though.)

You'll want to use that, if you do not want /some/path to match /some/path2/file . Otherwise, just use plain $TEMP .

If you are working on a truly ancient Unix, you can always work around the problems by using wc for length, cut for string manipulation, and optionally tr for case conversion:
Code:
FILE1="/some/path"
FILE2="/some/other/path"

LEN1=`echo -n "$FILE1" | wc -c | tr -cd 0-9`
LEN2=`echo -n "$FILE2" | wc -c | tr -cd 0-9`
if [ $LEN1 -gt 0 ] && [ $LEN2 -gt 0 ]; then
    TEMP1="`echo -n "$FILE1" | tr a-z A-Z | cut -b1-$LEN2`"
    TEMP2="`echo -n "$FILE2" | tr a-z A-Z | cut -b1-$LEN1`"
    if [ ":$TEMP1" == ":$TEMP2" ]; then
        echo "FILE1 ($FILE1) is a prefix of FILE2 ($FILE2) or vice versa."
    fi
fi
The above does case insensitive comparison; if you want case sensitive comparison, just replace the | tr a-z A-Z | above with | .

Old shells don't always support $(cmd) subshells, so I use the ancient but equivalent `cmd` instead.

Note that the lengths are intentionally swapped, so that TEMP1 and TEMP2 end up being the same length. I put the colons into the compared patterns just in case your shell does not compare empty strings properly.
 
  


Reply


Thread Tools Search this Thread
Search this Thread:

Advanced Search

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is Off
HTML code is Off



Similar Threads
Thread Thread Starter Forum Replies Last Post
Korn Shell problem / User Monitoring script Fragments Programming 1 03-18-2010 07:09 AM
shell script comparison for two file(text) character wise vaibhavs17 Programming 4 03-01-2010 01:05 PM
Korn shell script mmahulo Linux - Newbie 9 12-17-2008 09:19 AM
script in korn shell disruptive Programming 15 02-22-2007 10:18 AM
Korn shell script Muzica Solaris / OpenSolaris 4 09-06-2004 12:47 PM

LinuxQuestions.org > Forums > Non-*NIX Forums > Programming

All times are GMT -5. The time now is 06:38 AM.

Main Menu
Advertisement
My LQ
Write for LQ
LinuxQuestions.org is looking for people interested in writing Editorials, Articles, Reviews, and more. If you'd like to contribute content, let us know.
Main Menu
Syndicate
RSS1  Latest Threads
RSS1  LQ News
Twitter: @linuxquestions
Open Source Consulting | Domain Registration