Compare strings inside in the two different direct

2019-08-31 03:18发布

I don't get the scenario of this given code. All I wanted is to compare the files that is given below. But, in this script nothings happen. I assume that this given code can executed wherever like in /root and it will run. Please check this out.

#!/bin/bash
for file in /var/files/sub/old/*
do
# Strip path from file name
file="${file##*/}"

# Strip everything after the first hyphen
prefix="${file%%-*}-"

# Strip everything before the second-to-last dot
suffix="$(echo $file | awk -F. '{ print "."$(NF-1)"."$NF }')"

# Create new file name from $prefix and $suffix, and any version number
new=$(echo "/var/files/new/${prefix}"*"${suffix}")

# If file exists in the 'new' folder:
if test -f "${new}"
then
# Do string comparison to see if new file is lexicographically "greater than" old
if [[ "${new##*/}" > "${file}" ]]
then
  # If so, delete the old version.
  rm /var/sub/files/old/"${file}"
else
  # 'new' file is NOT newer, delete it instead.
  rm "${new}"
  fi
  fi
done

# Move all new files into the old folder.
mv /var/files/new/* /var/files/sub/old/

Example files inside of each sub- directories ..

/var/files/sub/old/
firefox-24.5.0-1.el5_10.i386.rpm
firefox-24.5.0-1.el5_10.x86_64.rpm
google-1.6.0-openjdk-1.6.0.0-5.1.13.3.el5_10.x86_64.rpm
google-1.6.0-openjdk-demo-1.6.0.0-5.1.13.3.el5_10.x86_64.rpm

/var/files/new/
firefox-25.5.0-1.el5_10.i386.rpm
firefox-25.5.0-1.el5_10.x86_64.rpm
ie-1.6.0-openjdk-devel-1.6.0.0-5.1.13.3.el5_10.x86_64.rpm
ie-1.6.0-openjdk-javadoc-1.6.0.0-5.1.13.3.el5_10.x86_64.rpm
ie-1.6.0-openjdk-src-1.6.0.0-5.1.13.3.el5_10.x86_64.rpm
google-2.6.0-openjdk-demo-1.6.0.0-5.1.13.3.el5_10.x86_64.rpm

In this instance, I want to get the files that are the same. So the files that are the same in the given example are:

  • firefox-24.5.0-1.el5_10.i386.rpm
  • firefox-24.5.0-1.el5_10.x86_64.rpm
  • google-1.6.0-openjdk-demo-1.6.0.0-5.1.13.3.el5_10.x86_64.rpm

in the old/ directory and for the new/ directory the equivalents are:

  • firefox-25.5.0-1.el5_10.i386.rpm
  • firefox-25.5.0-1.el5_10.x86_64.rpm
  • google-2.6.0-openjdk-demo-1.6.0.0-5.1.13.3.el5_10.x86_64.rpm

The files have similarity for their first characters. It will display in the terminal. After that, there will be another comparing again of the files and the comparison is about which file is more updated one by the number after the name of the file like: firefox-24.5.0-1.el5_10.i386.rpm compared with firefox-25.5.0-1.el5_10.i386.rpm. So in that instance the firefox-24.5.0-1.el5_10.i386.rpm will be replaced by firefox-25.5.0-1.el5_10.i386.rpm because it has a greater value and more updated one and same as other files that are similar. And if the old one is removed and the new will take replacement of it.

So at this moment after the script has been executed the output will be like this.

/var/files/sub/old/
google-1.6.0-openjdk-1.6.0.0-5.1.13.3.el5_10.x86_64.rpm
firefox-25.5.0-1.el5_10.i386.rpm
firefox-25.5.0-1.el5_10.x86_64.rpm
ie-1.6.0-openjdk-devel-1.6.0.0-5.1.13.3.el5_10.x86_64.rpm
ie-1.6.0-openjdk-javadoc-1.6.0.0-5.1.13.3.el5_10.x86_64.rpm
ie-1.6.0-openjdk-src-1.6.0.0-5.1.13.3.el5_10.x86_64.rpm
google-2.6.0-openjdk-demo-1.6.0.0-5.1.13.3.el5_10.x86_64.rpm

/var/files/new/
<<empty all files here  must to moved to other directory take as a replacement>>

Can anyone help me to make a script for this ? above is just an example. Let's assume that there are lots of files to considered as similar and need to removed and moved.

3条回答
贼婆χ
2楼-- · 2019-08-31 04:04

A bash script that does the checking. Here's how it works:

  1. Traverse over each file in the old files directory. Get the prefix (package name with no version, architecture, etc), eg. firefox-; get the suffix (architecture.rpm), eg. .i386.rpm.
  2. Attempt to match prefix and suffix with any version number within the new files directory, ie. firefox-*.i386.rpm. If there is a match, $new will contain the file name, eg. firefox-25.5.0-1.el5_10.i386.rpm; if no match, $new will equal the literal string firefox-*.i386.rpm which is not a file.
  3. Check new files directory for existence of $new.
  4. If it exists, check that $new is indeed newer than the old version. This is done by lexicographical string comparison, ie. firefox-24.5.0-1.el5_10.i386.rpm is less than firefox-25.5.0-1.el5_10.i386.rpm because it comes earlier in the alphabet. Conveniently, sane versioning schemes also happen to be alphabetical. NB: this may fail, for example, when comparing version 2 to version 10.
  5. A new version of a file in the old files directory has been found! In this case, get rid of the old file with rm. If the file in the new directory is not newer, then delete it instead.
  6. Done removing old versions. Old files directory has only files without newer versions.
  7. Move all new files into old directory, leaving newest files in old directory, and new directory empty.

#!/bin/bash
for file in /var/files/sub/old/*
do
  # Strip path from file name
  file="${file##*/}"

  # Strip everything after the first hyphen
  prefix="${file%%-*}-"

  # Strip everything before the second-to-last dot
  suffix="$(echo $file | awk -F. '{ print "."$(NF-1)"."$NF }')"

  # Create new file name from $prefix and $suffix, and any version number
  new=$(echo "/var/files/new/${prefix}"*"${suffix}")

  # If file exists in the 'new' folder:
  if test -f "${new}"
  then
    # Do string comparison to see if new file is lexicographically "greater than" old
    if [[ "${new##*/}" > "${file}" ]]
    then
      # If so, delete the old version.
      rm /var/sub/files/old/"${file}"
    else
      # 'new' file is NOT newer, delete it instead.
      rm "${new}"
    fi
  fi
done

# Move all new files into the old folder.
mv /var/files/new/* /var/files/sub/old/
查看更多
趁早两清
3楼-- · 2019-08-31 04:14

If the goal here is to have the newrpms directory have only the newest version of each RPM from a combination of sources then you most likely want to simply combine all the files in a single directory and then use the repomanage tool (from the yum-utils package, at least on CentOS) to have it inform you which of the RPMS are old and remove them.

Something like:

repomanage --old combined_rpms_directory | xargs -r rm

As to your initial script

for i in $(\ls -d ./new/*);
do 
    diff ${i} newrpms/; 
    rm ${i}
done

You generally don't want to "parse" the output from ls, especially when a glob will do what you want just as easily (for i in ./new/* in this case).

diff ${i} newrpms/ is attempting to diff a file and a directory (or two directories if your ls/glob happened to catch a directory) but in neither case will diff do what you want there. That being said what diff does doesn't really matter because, as Barmar said in his comment

your script is removing them without testing the result of diff

查看更多
萌系小妹纸
4楼-- · 2019-08-31 04:24

You can use rpm to get the name of the package without version or architecture strings:

rpm -qi -p /firefox-25.5.0-1.el5_10.i386.rpm

Gives:

Name        : firefox
Version     : 25.5.0
Release     : 1.el5_10
Architecture: i386
....

So you can compare the Names to find related packages.

查看更多
登录 后发表回答