使用数组比较两个不同目录中的字符串

时间:2014-06-03 02:56:59

标签: arrays bash loops awk seq

我没有得到这个给定代码的场景。我想要的只是比较下面给出的文件。但是,在这个剧本中没有发生。我假设这个给定的代码可以在/ root中执行,并且它将运行。请检查一下。

#!/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/

每个子目录中的示例文件..

/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

在这种情况下,我想获得相同的文件。因此,给定示例中相同的文件是:

  • 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
old/目录中的

new/目录中的等价物是:

  • 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

这些文件的第一个字符具有相似性。它将显示在终端中。之后,将再次对文件进行比较,并且比较是关于哪个文件更新更新一个文件名后面的数字,如:firefox-24.5.0-1.el5_10.i386.rpmfirefox-25.5.0-1.el5_10.i386.rpm进行比较。因此,在这种情况下,firefox-24.5.0-1.el5_10.i386.rpm将被firefox-25.5.0-1.el5_10.i386.rpm替换,因为它具有更大的值和更新的值,并且与其他类似的文件相同。如果旧的一个被删除,新的将取代它。

所以在执行脚本之后的这一刻,输出将是这样的。

/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>>

任何人都可以帮我制作一个脚本吗?上面只是一个例子。让我们假设有很多文件被认为是相似的,需要删除和移动。

3 个答案:

答案 0 :(得分:1)

您可以使用rpm获取没有版本或体系结构字符串的包的名称:

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

给出:

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

因此,您可以比较Name以查找相关的包。

答案 1 :(得分:0)

如果这里的目标是让newrpms目录只包含来自多个源的每个RPM的最新版本,那么您很可能只想将所有文件合并到一个目录中,然后使用repomanage工具(来自yum-utils包,至少在CentOS上)让它通知你哪个RPMS是旧的并删除它们。

类似的东西:

repomanage --old combined_rpms_directory | xargs -r rm

关于你的初始剧本

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

您通常不想解析&#34;来自ls的输出,特别是当glob可以轻松地执行你想要的操作时(在这种情况下为for i in ./new/*)。

diff ${i} newrpms/正在尝试区分文件和目录(如果你的ls / glob恰好捕获了一个目录,则会有两个目录),但在这两种情况下都不会做你想做的事情。据说,正如巴尔玛在评论中所说的那样,差异所做的并不重要。

  

你的脚本正在移除它们而不测试diff

的结果

答案 2 :(得分:0)

执行检查的bash脚本。以下是它的工作原理:

  1. 遍历旧文件目录中的每个文件。获取前缀(包名称没有版本,体系结构等),例如。 firefox-;得到后缀(architecture.rpm),例如。 .i386.rpm
  2. 尝试将前缀和后缀与新文件目录中的任何版本号匹配,即。 firefox-*.i386.rpm。如果匹配,$new将包含文件名,例如。 firefox-25.5.0-1.el5_10.i386.rpm;如果不匹配,$new将等于不是文件的文字字符串firefox-*.i386.rpm
  3. 检查新文件目录是否存在$new
  4. 如果存在,请检查$new 确实是否比旧版本更新。这是通过词典字符串比较完成的,即。 firefox-24.5.0-1.el5_10.i386.rpm 小于 firefox-25.5.0-1.el5_10.i386.rpm,因为它出现在字母表的前面。方便的是,理智的版本控制方案也恰好是按字母顺序排列的。 NB :例如,将版本2与版本10进行比较时,可能会失败。
  5. 找到旧文件目录中的新版本文件!在这种情况下,请使用rm删除旧文件。如果新目录中的文件更新,则删除 it
  6. 完成删除旧版本。旧文件目录只包含没有较新版本的文件。
  7. 将所有新文件移动到旧目录中,将最新文件保留在旧目录中,将新目录保留为空。

  8. #!/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/