开发者

I want a to compare a variable with files in a directory and output the equals

I am making a bash script where I want to find files that are equal to a variable. The equals will then be used.

I want to use "mogrify" to shrink a couple of image files that have the same name as the ones i gather from a list (similar to "dpkg -l"). It is not "dpkg -l" I am using but it is similar. My problem is that it prints all the files not just the equals. I am pretty sure this could be done with awk instead of a for-loop but I do not know how.

prog="`dpkg -l | awk '{print $1}'`"

for file in $dirone* $dirtwo*
do
     if [ "basename ${file}" = "${prog}" ]; then
         echo ${file} are equal
     else
         echo ${file} are not equal
     fi
done

C开发者_StackOverflow社区ould you please help me get this working?


First, I think there's a small typo. if [ "basename ${file}" =... should have backticks inside the double quotes, just like the prog=... line at the top does.

Second, if $prog is a multi-line string (like dpkg -l) you can't really compare a filename to the entire list. Instead you have to compare one item at a time to the filename.

Here's an example using dpkg and /usr/bin

#!/bin/bash
progs="`dpkg -l | awk '{print $2}'`"

for file in /usr/bin/*
do
    base=`basename ${file}`

    for prog in ${progs}
    do
        if [ "${base}" = "${prog}" ]; then
            echo "${file}" matches "${prog}"
        fi
    done
done


The condition "$file = $prog" is a single string. You should try "$file" = "$prog" instead.

The following transcript shows the fix:

pax> ls -1 qq*
qq
qq.c
qq.cpp

pax> export xx=qq.cpp

pax> for file in qq* ; do
         if [[ "${file} = ${xx}" ]] ; then
             echo .....${file} equal
         else
             echo .....${file} not equal
         fi
     done
.....qq equal
.....qq.c equal
.....qq.cpp equal

pax> for file in qq* ; do
         if [[ "${file}" = "${xx}" ]] ; then
             echo .....${file} equal
         else
             echo .....${file} not equal
         fi
     done
.....qq not equal
.....qq.c not equal
.....qq.cpp equal

You can see in the last bit of output that only qq.cpp is shown as equal since it's the only one that matches ${xx}.

The reason you're getting true is because that's what non-empty strings will give you:

pax> if [[ "" ]] ; then
         echo .....equal
     fi

pax> if [[ "x" ]] ; then
         echo .....equal
     fi
.....equal

That's because that form is the string length checking variation. From the bash manpage under CONDITIONAL EXPRESSIONS:

string
-n string
          True if the length of string is non-zero.


Update:

The new code in your question won't quite work as expected. You need:

if [[ "$(basename ${file})" = "${prog}" ]]; then

to actually execute basename and use its output as the first part of the equality check.


you can use case/esac

case "$file" in
  "$prog" ) echo "same";;
esac
0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜