diff --git a/D/* copy.txt b/D/* copy.txt new file mode 100644 index 0000000..e69de29 diff --git a/D/*.txt b/D/*.txt new file mode 100644 index 0000000..e69de29 diff --git a/D/-.txt b/D/-.txt new file mode 100755 index 0000000..8baef1b --- /dev/null +++ b/D/-.txt @@ -0,0 +1 @@ +abc diff --git a/D/.a_readable copy.txt b/D/.a_readable copy.txt new file mode 100755 index 0000000..f2ba8f8 --- /dev/null +++ b/D/.a_readable copy.txt @@ -0,0 +1 @@ +abc \ No newline at end of file diff --git a/D/a_readable copy.txt b/D/a_readable copy.txt new file mode 100755 index 0000000..f2ba8f8 --- /dev/null +++ b/D/a_readable copy.txt @@ -0,0 +1 @@ +abc \ No newline at end of file diff --git a/D/readable.txt b/D/readable.txt new file mode 100755 index 0000000..f2ba8f8 --- /dev/null +++ b/D/readable.txt @@ -0,0 +1 @@ +abc \ No newline at end of file diff --git a/D/readable2.txt b/D/readable2.txt new file mode 100755 index 0000000..85df507 --- /dev/null +++ b/D/readable2.txt @@ -0,0 +1 @@ +abcd \ No newline at end of file diff --git a/D/unreadable.txt b/D/unreadable.txt new file mode 100644 index 0000000..e69de29 diff --git a/README.md b/README.md index 5de18b3..4f94b64 100644 --- a/README.md +++ b/README.md @@ -1,5 +1,5 @@ # SP-Assignment -Part 1: +# Part 1: Write a menu based shell script to do the following: • accept a string and a file name from the user as command line arguments. • displays the following menu @@ -9,3 +9,15 @@ c: insert the string at the end of the file d: insert at beginning of 5th line e: exit Script should also print an error message in case user gives less or more number of arguments. For option “d” if the number line is less than 5, error should be displayed. + +# Part 2: +Find duplicate files. Suppose you're working in a project where software (or people) create lots of files, many of them duplicates. You don't want the duplicates: you want just one copy of each, to save disk space. Write a shell script "sameln" that takes a single argument naming a directory D, finds all regular files immediately under D that are duplicates, and replaces the duplicates with hard links. Your script should not recursively examine all files that are in subdirectories of D; it should examine only files that are immediately in D. + +If your script finds two or more files that are duplicates, it should keep the file whose name is lexicographically first (for example, if the duplicates are named X, A, and B, it should keep A and replace X and B with hard links to A); however, it should prefer files whose name start with "." to other files (for example, if the duplicates are named .Y, .X, A, and B, it should keep .X and replace the others with hard links to .X). + +If your script finds a file in D that is not a regular file, it should silently ignore it; for example, it should silently ignore all symbolic links and directories. If your script has a problem reading a file (for example, if the file not readable to you), it should report the error and not treat it as a duplicate of any file. + +You need to worry about the cases where your script is given no arguments, or more than one argument and also be prepared to handle files whose names contain special characters like spaces, "*", and leading "–". + + +## Note :- Please check whether file names are same after cloning since windows doesn't support many file name characters of linux \ No newline at end of file diff --git a/assignmentPart1.sh b/assignmentPart1.sh deleted file mode 100644 index d0859c5..0000000 --- a/assignmentPart1.sh +++ /dev/null @@ -1,67 +0,0 @@ -dataInput=$1 -fileName=$2 -if test $# -lt 2 -then echo "supply 2 inputs" -exit 1 -fi -if test dataInput -a fileName -then - -echo "a: Search" -echo "b:Insert string at beginning of file" -echo "c:Insert string at end of file" -echo "d:Insert at beginning of 5th line" -echo "e:Exit" -while : -do -echo "enter your choice:" -read choice -case $choice in -"a") -if grep "$dataInput" $fileName -then - echo "$dataInput found in file" -else - echo "$dataInput do not found" -fi -;; -"b") -echo "Content of file before insertion" -cat $fileName -echo "$dataInput" >> newFile.txt - - cat $fileName>>newFile.txt - - mv newFile.txt $fileName - - echo "$dataInput added in beginning of file" -echo "Content of file after Insertion" -cat $fileName ;; -"c") echo "$dataInput" >> $fileName - echo "$dataInput added in end of file" - echo -n "content of file after insertion" - cat $fileName;; -"d") lines=0 - while read line - do - lines=`expr $lines + 1` - done< $fileName -echo $lines -if test $lines -lt 5 -then echo "file has lines less than 5" -else -sed -i '5s/^/dataInput/#&' $fileName -echo "$dataInput inserted" -echo -n "Content of file after insertion" -cat $fileName -fi;; - -"e") echo "Thankyou" - exit;; -*) echo "invalid choice";; -esac - -done -else -echo "invalid input" -fi diff --git a/new.doc b/new.doc new file mode 100755 index 0000000..e098e57 --- /dev/null +++ b/new.doc @@ -0,0 +1 @@ +this is the test line of the document!! diff --git a/part2.txt b/part2.txt new file mode 100644 index 0000000..f4000e5 --- /dev/null +++ b/part2.txt @@ -0,0 +1,37 @@ +script name:- sameln.sh + +Objective:- + +- Take directory name as command line parameter. +- Find duplicate regular files in that directory. +- Keep the file whose name is lexicographically first. +- Replace other duplicates with hardlinks of the file found previously. + +Explaination of the script + +step 1:- Check the number of parameters if we dont have directory name as input throw an error. +step 2:- Check if the entered parameter is directory or not with -d option in if statement. +step 3:- Change directory into specified directory. +step 4:- Run a loop through all the files present in the directory using * symbol and all hidden files with .* symbol +step 5:- Check if the loop variable (file name) is regular file or not. "" around the variable helps in case filenames have space and other special characters like asterisk. +step 6:- md5sum takes out hash value of the file using its contents and concatenates it to a file mdresult( contains 32 character hash and filename of each file). + In case a file is unreadable md5sum throws an error. +step 7:- dup_hash_all=($(cat mdresult | sort | uniq -w32 -d | cut -b 1-32)) + This command pipes the hash and filename list to sort command which sorts files according to hash and filename as uniq command needs sorted input, + then we find unique 32 characters(hash) -d option results in only duplicate values + then we cut the result to only contain first 32 charates(unique hash value) + then the () converts it into array. + Thus dup_hash_all contains array of unique hash values of duplicate files. +step 8:- Running a loop till total number of elements in the dup_hash_all array. +step 9:- cat mdresult | grep "${dup_hash_all[i]}" | sort | cut -d " " -f 3- > allFiles + Find all rows in mdresult with hash value same as value in dup_hash_all i.e unique hash of duplicate files, + then sort it and cut with delimiter " " and pick the third value(filename) and redirect those filenames to a temporary file allFiles. +step 10:- mapfiles command takes the allFiles file which contain duplicate filenames and converts it to array. + Array index 0 contains filename which we want to keep intact rest of the filename we will remove and create hard links from the first file. +step 11:- allFilesArray[0]=$(echo "${allFilesArray[0]}" | tr -d '\n') + Overwrite value of allFilesArray[0] with value after replacing unwanted charater(newline). +step 12:- run a loop from index 1 (second position) to rest of the array. +step 13:- Overwrite value of allFilesArray[j] with value after replacing unwanted charater(newline). +step 14:- Remove all files with filename present in second to the last position. +step 15:- Create hardlink of the deleted files which would have same filename as earlier from the filename present in first index. +Step 16:- Remove all the exra files created. diff --git a/prg.sh b/prg.sh new file mode 100755 index 0000000..b33a868 --- /dev/null +++ b/prg.sh @@ -0,0 +1,69 @@ +#!/bin/bash + +if [ $# != 2 ] +then + echo "ERROR! Improper Argument List"; + exit 1; +elif [ ! -f $2 ] +then + echo "File Does not exists,Please provide a valid input !! "; + exit 1; +fi +while true +do +echo "<---------------------------------My App----------------------------------->"; +echo "a: Search"; +echo "b: Insert the string at the begining of the file"; +echo "c: Insert the string at the end of the file"; +echo "d: Insert at begining of 5th Line"; +echo "e: exit"; +echo "Enter your choice : "; +read choice; +case "$choice" in + "a") + if grep -q $1 $2 + then + echo "String $1 Found in $2 file !!"; + else + echo "String $1 not Present in $2 file !!" + fi; + echo "";; + "b") + echo "Content of the original file is : "; + cat ./$2; + sed -i "1s/^/$1 /" $2; + echo "Content of the file $2 after inserting '$1' at the begining : "; + cat ./$2; + echo " "; + ;; + "c") + echo "Content of the original file is : "; + cat ./$2; + echo $1 >> ./$2; + echo "Content of the file $2 after inserting '$1' at the end : "; + cat ./$2; + echo " "; + ;; + "d") + lines=$(cat $2 | wc -l); + if [ $lines -lt 5 ] + then + echo "The file $2 does not have atleast 5 lines, hence cannot insert the string $1 at the 5th line !!"; + echo " "; + continue; + else + echo "Content of the Original file is :"; + cat $2; + sed -i "5s/^/$1 /" $2; + echo "Content of the file $2 after inserting '$1' at the 5th line :" + cat $2; + echo " "; + fi + ;; + + "e") + echo "Exiting......"; + exit 1;; + *) echo "Invalid choice!!";; +esac +done diff --git a/sameln.sh b/sameln.sh new file mode 100755 index 0000000..4a1dc4c --- /dev/null +++ b/sameln.sh @@ -0,0 +1,42 @@ +#!/bin/bash +if [ $# != 1 ] +then + echo "ERROR! Improper Argument List" + exit 1 +else + if [ -d $1 ] + then + cd $1 + for item in * .* # .* satisfies filename with "." + do + if [ -f "$item" ] # satisfies regular file constraint "" helps in filenames with space and asterisk + then + md5sum "./$item" >> mdresult # The ./ handles - type files + fi + done + # stores unique hash values + dup_hash_all=($(cat mdresult | sort | uniq -w32 -d | cut -b 1-32)) + for ((i = 0 ; i < ${#dup_hash_all[*]} ; i++)); do + cat mdresult | grep "${dup_hash_all[i]}" | sort | cut -d " " -f 3- > allFiles + # convert contents of allFiles file into array + mapfile allFilesArray < allFiles + # trim unwanted newline character from the end. + allFilesArray[0]=$(echo "${allFilesArray[0]}" | tr -d '\n') + for((j = 1; j < ${#allFilesArray[@]}; j++)) + do + # trim unwanted newline character from the end. + allFilesArray[j]=$(echo "${allFilesArray[j]}" | tr -d '\n') + # remove the duplicate file + rm "${allFilesArray[j]}" + # create hardlink + ln "${allFilesArray[0]}" "${allFilesArray[j]}" + echo "${allFilesArray[j]} has been hard linked to ${allFilesArray[0]}" + done + done + # removing extra files. + rm mdresult + rm allFiles + else + echo "Directory does not exist" + fi +fi \ No newline at end of file