0

How to write a shell script, which will count and print/echo how many changes were made executing an SED command...

Eg: Let's use the SED command, to delete every line if it matches a specific character.

sed '/@gmail.com/d' F1.txt > RESULT.txt

F1.txt file contains:

abc123@gmail.com
zyz123@gmail.com
fgh456@yahoo.com
ght4789@msn.com

The output of this file would be:

fgh456@yahoo.com
ght4789@msn.com

Therefore it matched two lines and deleted the two lines.

Now how to echo this in a Shell script with an Echo, suggesting how many lines were modified/deleted by this SED command?

It should sound and Print/Echo, 2 lines where deleted. Can you please help how to make this shell script?

#!/bin/bash
sed '/@gmail.com/d' F1.txt > RESULT.txt
  • You can use wc -l on both files, and calculate the difference. – AFH Jan 24 at 15:50
  • Can you please help me how to write a Shell script, which will Echo the count of changes made using that SED command? – Joney Walker Jan 24 at 15:57
  • Use $(wc -l <FileName) to return each line count and $((ArithmeticExpression)) to return the difference. – AFH Jan 24 at 16:06
  • I understood how to use wc -l but I am not able to implement $((ArithmeticExpression)). Can you please help me with that by writing the full line of code. plz. – Joney Walker Jan 25 at 10:02
  • Did you look up $(( ... )) in the manual? What didn't you understand? – AFH Jan 25 at 14:03
1

If you are ok doing it with two commands, you can do something like the following:

NUM_DELETIONS=$( grep "@gmail.com" F1.txt | wc -l )
sed '/@gmail.com/d' F1.txt > RESULT.txt

echo "${NUM_DELETIONS} lines were deleted from F1.txt"

If you wanted to write it up as a quick and dirty bash script, you might considering doing it like this:

#!/bin/bash

usage(){
    echo "$0 <source_file> <output_file> <removal_text>"
}

SOURCE_FILE="${1}"
OUTPUT_FILE="${2}"
REMOVAL_TEXT="${3}"

[[ ! -r "${SOURCE_FILE}" ]] && usage && exit 1
[[ -z "${REMOVAL_TEXT}" ]] && usage && exit 1

NUM_DELETIONS=$( grep "${REMOVAL_TEXT}" "${SOURCE_FILE}" | wc -l )
sed "/${REMOVAL_TEXT}/d" "${SOURCE_FILE}" > "${OUTPUT_FILE}"

echo "${NUM_DELETIONS} lines were deleted from "${SOURCE_FILE}""
  • 1
    Naming convention. – Kamil Maciorowski Jan 24 at 16:38
  • Thanks a lot.. This works.. I already figured out to modify this in case of substitution. But can you please explain what this two lines 11 & 12 does: [[ ! -r "${SOURCE_FILE}" ]] && usage && exit 1 ------- [[ -z "${REMOVAL_TEXT}" ]] && usage && exit 1 – Joney Walker Jan 25 at 7:49
  • Those lines validate your command line arguments. It is usually good practice to validate the arguments to the program before using them. If the arguments are incorrect, the usage statement will be printed to help the user fix the problem. – Chuck Wolber Jan 27 at 7:52
  • Ok I see... Why have your used [! -r] in case of Source-File and [-z] in case of Removal Text. can you please explain the difference between them? – Joney Walker Jan 28 at 9:12
  • 1
    Those are bash conditional expressions. Bash has all sorts of conditional expressions to do all sorts of useful things. In the above case -z is true if the variable is empty. The -r expression is true if the file exists and is readable. If you want to see the entire list of conditional expressions, just run the command man bash and search for CONDITIONAL EXPRESSIONS. P.S. Gentle reminder - you might want to consider marking one of the answers correct on your question. It rewards the person answering you. – Chuck Wolber Jan 29 at 22:43
2

Here's one way to do it:

echo $(( $(wc -l < F1.txt) - $(wc -l < RESULT.txt) ))

The wc -l is a count of lines, and < makes it read from "standard input" (which is essentially a hack to stop it printing the filename)

Each wc is wrapped in $() which just substitutes in the output.

The $(( ... )) is shell arithmetic (as someone said in a comment). Notice the minus sign in the middle.

Variables might make it clearer; here's another version of the same thing:

all=$(wc -l < F1.txt)
sed=$(wc -l < RESULT.txt)
echo $(($all - $sed))

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.