0

These are my folders/files:

backup/
├── folder1
│   ├── file1.txt
│   ├── file2.txt
│   └── file3.txt
└── folder2

file1.txt (is empty) file2.txt (there is only X inside the file) file3 (last created empty)

My Script:

#!/bin/sh
#config-checker.sh

#First loop looks at each folder in backup/. 

for j in `ls backup/  -1t` 

do

    #change directory to other folders
    cd backup/${j}/
    N=0

    #Grab the two newest files. Add them to an array called FILE
    for i in `ls -1t | head -2`
    do
        FILE[$N]=$i
        N=$N+1
    done

    #diff the two files in FILE
    var=`diff ${FILE[0]} ${FILE[1]}`

    #if a diff exists, show it
    if [[ ${var} ]]
        then
        #script here takes two variables; the name of the folder and the content of the diff
        echo $j "${var}"
    fi
done

It's not getting me the diff on the file, my output is this:

./config-checker.sh: 17: FILE[0]=file2: not found ./config-checker.sh: 17: FILE[0+1]=file3: not found ./config-checker.sh: 1: Bad substitution folder1 ./config-checker.sh: 11: cd: can't cd to backup/folder2 ./config-checker.sh: 17: FILE[0]=file2: not found ./config-checker.sh: 17: FILE[0+1]=file3: not found ./config-checker.sh: 1: Bad substitution folder2

Not sure what Im missing here. Any help would be appreciated. Thank you

Alex
  • 13
  • 2
  • 2
    https://stackoverflow.com/questions/776854/how-do-i-compare-two-source-trees-in-linux? – knittl Jan 09 '23 at 20:31
  • Thanks, but I need to compare files. When I run the 2nd FOR manually into the bash inside the folder, it gets me what I need and the DIFF works, but the entire script gets me an odd output. – Alex Jan 09 '23 at 20:38
  • 1
    You are `cd`ing into another directory, but never changing back. Since you are using relative paths, they are sensitive to the current working directory. Either use absolute paths or change back to the original directory. – knittl Jan 09 '23 at 20:40
  • Adding one works different. Try `N=0; N=$N+1; echo $N`. Use lowercase variables and `((n=n+1))` or `((n++))`. – Walter A Jan 09 '23 at 21:47
  • Your solution won't work for files with spaces or newlines. – Walter A Jan 09 '23 at 21:48
  • thank you all. The issue were here: where is "backup/" I had to add in the full path of the folder I wanted to scan then fix the below. var="$(diff ${FILE[0]} ${FILE[1]})" – Alex Jan 09 '23 at 22:02

1 Answers1

0

Firstly - I think knittl comment is correct in stating you don't return from the cd.

Secondly - I've edited my response. If I now understand correctly, you want to walk all the sub-folders of a folder. For each sub-folder, diff the two most recent files in the sub-folder, if there are two, output the name of the first file and the diff.

For completeness I've amended my answer to what I would have written, which is not so different to your original solution:

topfolder=~/tmp/test
for folder in  $(ls -1t $topfolder)
do  
   set --  $(ls -1t  $topfolder/$folder | head -2) 
   if [ $# -ne 2 ] || diff -q $topfolder/$folder/$1 $topfolder/$folder/$2 > /dev/null
   then
       : # Do nothing
   else
       echo $1 
       diff $topfolder/$folder/$1 $topfolder/$folder/$2
   fi
done

As point of difference, I do a quick diff to find out if there is a difference. By doing so I'm avoiding saving a potentially unlimited amount of diff text in memory. Whether it is worth taking such an approach depends on factors such as the likely size of the differences and the number of executions the loop is likely to make.

  • Thanks, but this won't work for the original script - folder/file are only an example. basically I have an ansible playbook which grap over 100 switches configuration and save into a folder call backup/ inside this folder I use inventory_hostname, and the config saved in is inventory_hostname.txt - The script is looping through each folder in the directory where I am storing switch configs, then grabbing the two newest files in each folder and performing a diff. diff will output any changes from one file to the other if any changes exist. – Alex Jan 09 '23 at 20:50
  • Awesome Michael, thank you very much, looks tidy and works the same way! Cheers – Alex Jan 10 '23 at 10:00
  • BTW, the script as written won't cope with spaces in filenames. I felt it was better not to overcomplicate the solution because that doesn't seem to be a requirement. – Michael Hamilton Jan 10 '23 at 18:45