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 '19 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 '19 at 15:57
  • Use $(wc -l <FileName) to return each line count and $((ArithmeticExpression)) to return the difference. – AFH Jan 24 '19 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 '19 at 10:02
  • Did you look up $(( ... )) in the manual? What didn't you understand? – AFH Jan 25 '19 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}""
| improve this answer | |
  • 1
    Naming convention. – Kamil Maciorowski Jan 24 '19 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 '19 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 '19 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 '19 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 '19 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))
| improve this answer | |

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.