使用带数组和值引号的SHELL进行比较时出现问题[重复]

g2ieeal7  于 2022-12-13  发布在  Shell
关注(0)|答案(1)|浏览(121)

此问题在此处已有答案

How can I store the "find" command results as an array in Bash(8个答案)
5天前关闭。
嗨,伙计们,我有一个问题,而使用差异。
在我的脚本中,我试图将1个目录中的所有文件与2个其他目录中的所有文件进行比较。
下面是我的脚本:`

#!/bin/bash

files1=()
files2=()

# Directories to compare. Adding quotes at the begining and at the end of each files found in content1 & content3

content2=$(find /data/logs -name "*.log" -type f)
content1=$(find /data/other/logs1 -type f | sed 's/^/"/g' | sed 's/$/"/g')
content3=$(find /data/other/logs2 -type f | sed 's/^/"/g' | sed 's/$/"/g')

# ADDING CONTENT INTO FILES1 & FILES2 ARRAY
while read -r line; do
        files1+=("$line")
done <<< "$content1"

# content1 and content3 goes into the same array
while read -r line3;do
        files1+=("$line3")
done <<< "$content3"

while read -r line2; do
        files2+=("$line2")
done <<< "$content2"

# Here i'm trying to compare 1 by 1 the files in files2 to all files1
for ((i=0; i<${#files2[@]}; i++))
do
        for ((j=0; j<${#files1[@]}; j++))
        do
                if [[ -n ${files2[$i]} ]];then
                        diff -s "${files2[$i]}" "${files1[$j]}" > /dev/null
                        if [[ $? == 0 ]]; then
                                echo ${files1[$j]} "est identique a" ${files2[$i]}
                                unset 'files2[$i]'
                                break
                        fi
                fi
        done
done

#SHOW THE FILES WHO DIDN'T MATCHED
echo ${files2[@]}

当我试图提出异议时,我遇到了以下问题:比较:“/数据/内容3/其他/日志2/个人日志/某些日志. log”:无此文件或目录 但当我在做ll "/data/content3/other/log2/perso log/somelog.log" -rw-rw-r-- 2 lopom lopom 551M 30 oct. 18:53 '/data/content3/other/logs2/perso log/somelog.log'`
所以文件存在。
我需要这些引号,因为有时路径中会有空格
有人知道怎么修吗?

  • 谢谢-谢谢
    我已经尝试过用单引号来更改引号,但它没有修复它
643ylb08

643ylb081#

首先,别这样-

content2=$(find /data/logs -name "*.log" -type f)
content1=$(find /data/other/logs1 -type f | sed 's/^/"/g' | sed 's/$/"/g')
content3=$(find /data/other/logs2 -type f | sed 's/^/"/g' | sed 's/$/"/g')

不要把所有这些都堆到一个变量里,这会带来十种麻烦。更重要的是,那些sed调用把引号作为文件名的一部分嵌入到数据中,这可能是导致diff崩溃的原因,因为实际上没有文件名中有引号。
另外,如果你放弃输出,只使用diff来检查文件是否相同,可以尝试cmp-ssilent 的,而且速度快得多,因为它在第一个不同的字节处退出,而不阅读两个文件的其余部分并生成报告。如果有很多文件,这将加起来。
如果日志是目录中仅有的内容,您不必扫描子目录,并且文件名不能同时出现在/data/other/logs 1和/data/other/logs 2中,但您很确定它至少会出现在其中一个目录中...那么简化以下步骤:

for f in /data/logs/*.log                     # I'll assume these are all files...
do  t=/data/other/logs[12]/"${f#/data/logs/}" # always just one?
    if cmp -s "$f" "$t"                       # cmp -s *has* no output
    then echo "$t est identique a $f"         # files are same
    elif [[ -e "$t" ]]                        # check t exists
    then echo "$t diffère de $f"              # maybe ls -l "$f" "$t" ?  
    else echo "$t n'existe pas"               # report it does not
    fi
done

这不需要数组、findsed调用等。
如果确实需要读取子目录,可以使用shopt来处理glob,这样就不必担心使用read解析奇怪的字符(出于某些原因,请参阅https://mywiki.wooledge.org/ParsingLs)。

shopt -s globstar
for f in /data/logs/**/*.log   # globstar makes ** match at arbitrary depth
do  for t in /data/other/logs[12]/**/"${f#/data/logs/}" # if >1 possible hit
    do  if cmp -s "$f" "$t" 
        then echo "$t est identique a $f"
        elif [[ -e "$t" ]]
        then echo "$t diffère de $f" 
        else echo "$t n'existe pas"  # $t will be the glob, one iteration
        fi
    done
done

相关问题