DEV Community

Janak Shrestha
Janak Shrestha

Posted on

Linux String Substitute (sed)

There is some data on Nautilus App Server 1 in Stratos DC. Data needs to be altered in several of the files. On Nautilus App Server 1, alter the /home/BSD.txt file as per details given below:

a. Delete all lines containing word code and save results in /home/BSD_DELETE.txt file. (Please be aware of case sensitivity)

b. Replace all occurrence of word from to for and save results in /home/BSD_REPLACE.txt file.

Note: Let's say you are asked to replace word to with from. In that case, make sure not to alter any words containing the string itself; for example up*to, contributo*r etc.


Solution

Step 1: Connect to App Server 1 (stapp01)

ssh tony@stapp01
# Password: Ir0nM@n
Enter fullscreen mode Exit fullscreen mode

Step 2: Switch to root (if needed)

sudo su -
# Password: Ir0nM@n
Enter fullscreen mode Exit fullscreen mode

Step 3: Verify the file exists

ls -la /home/BSD.txt
Enter fullscreen mode Exit fullscreen mode

Step 4: Create the processed files

a. Delete all lines containing "code"

grep -v "code" /home/BSD.txt > /home/BSD_DELETE.txt
Enter fullscreen mode Exit fullscreen mode

b. Replace all occurrences of "from" with "for" (exact word match)

sed -E 's/\bfrom\b/for/g' /home/BSD.txt > /home/BSD_REPLACE.txt
Enter fullscreen mode Exit fullscreen mode

Note: \b ensures exact word match (word boundaries), preventing partial matches like "from" in "fromage" or "frolic".

Step 5: Verify the results

# Check files created
ls -la /home/BSD_DELETE.txt /home/BSD_REPLACE.txt

# Verify line counts
echo "Original lines: $(wc -l < /home/BSD.txt)"
echo "After deleting 'code' lines: $(wc -l < /home/BSD_DELETE.txt)"
echo "After replacing 'from' with 'for': $(wc -l < /home/BSD_REPLACE.txt)"

# Verify no "code" lines in BSD_DELETE.txt
grep "code" /home/BSD_DELETE.txt | wc -l
# Should output: 0

# Verify replacements
echo "Original 'from' count: $(grep -o '\bfrom\b' /home/BSD.txt | wc -l)"
echo "New 'for' count: $(grep -o '\bfor\b' /home/BSD_REPLACE.txt | wc -l)"
Enter fullscreen mode Exit fullscreen mode

One-Line Commands

From jump host with password:

echo 'Ir0nM@n' | ssh tony@stapp01 "sudo -S bash -c 'grep -v \"code\" /home/BSD.txt > /home/BSD_DELETE.txt && sed -E \"s/\\bfrom\\b/for/g\" /home/BSD.txt > /home/BSD_REPLACE.txt && ls -la /home/BSD_DELETE.txt /home/BSD_REPLACE.txt'"
Enter fullscreen mode Exit fullscreen mode

Using heredoc (Recommended):

ssh tony@stapp01 << 'EOF'
echo 'Ir0nM@n' | sudo -S bash -c '
echo "=== Part A: Delete lines containing 'code' ==="
grep -v "code" /home/BSD.txt > /home/BSD_DELETE.txt
echo "✓ BSD_DELETE.txt created"

echo ""
echo "=== Part B: Replace 'from' with 'for' ==="
sed -E "s/\\bfrom\\b/for/g" /home/BSD.txt > /home/BSD_REPLACE.txt
echo "✓ BSD_REPLACE.txt created"

echo ""
echo "=== Verification ==="
ls -la /home/BSD_DELETE.txt /home/BSD_REPLACE.txt

echo ""
echo "Line counts:"
echo "Original: $(wc -l < /home/BSD.txt)"
echo "Delete: $(wc -l < /home/BSD_DELETE.txt)"
echo "Replace: $(wc -l < /home/BSD_REPLACE.txt)"

echo ""
echo "Checking for 'code' in BSD_DELETE.txt:"
grep "code" /home/BSD_DELETE.txt | wc -l

echo ""
echo "Checking replacements:"
echo "Original 'from' count: $(grep -o "\\bfrom\\b" /home/BSD.txt | wc -l)"
echo "New 'for' count: $(grep -o "\\bfor\\b" /home/BSD_REPLACE.txt | wc -l)"

echo ""
echo "✅ Files created successfully!"
'
EOF
Enter fullscreen mode Exit fullscreen mode

Step-by-Step Interactive Commands

# Connect to stapp01
ssh tony@stapp01
# Password: Ir0nM@n

# Become root
sudo su -
# Password: Ir0nM@n

# Step 1: Check the original file
echo "=== Original file ==="
wc -l /home/BSD.txt
head -20 /home/BSD.txt

# Step 2: Delete lines containing "code"
echo "=== Creating BSD_DELETE.txt ==="
grep -v "code" /home/BSD.txt > /home/BSD_DELETE.txt

# Step 3: Replace "from" with "for"
echo "=== Creating BSD_REPLACE.txt ==="
sed -E 's/\bfrom\b/for/g' /home/BSD.txt > /home/BSD_REPLACE.txt

# Step 4: Verify
echo "=== Verification ==="
echo "Original: $(wc -l < /home/BSD.txt) lines"
echo "Delete: $(wc -l < /home/BSD_DELETE.txt) lines"
echo "Replace: $(wc -l < /home/BSD_REPLACE.txt) lines"

# Step 5: Check for "code" in BSD_DELETE.txt (should be none)
echo "=== Checking BSD_DELETE.txt for 'code' ==="
grep "code" /home/BSD_DELETE.txt | wc -l
echo "✓ No 'code' lines found"

# Step 6: Check replacements
echo "=== Checking replacements ==="
echo "Original 'from' count: $(grep -o '\bfrom\b' /home/BSD.txt | wc -l)"
echo "New 'for' count: $(grep -o '\bfor\b' /home/BSD_REPLACE.txt | wc -l)"

# Step 7: Preview results
echo "=== BSD_DELETE.txt sample ==="
head -10 /home/BSD_DELETE.txt

echo "=== BSD_REPLACE.txt sample ==="
head -10 /home/BSD_REPLACE.txt

# Exit
exit
exit
Enter fullscreen mode Exit fullscreen mode

Expected Output

[root@stapp01 ~]# grep -v "code" /home/BSD.txt > /home/BSD_DELETE.txt
[root@stapp01 ~]# sed -E 's/\bfrom\b/for/g' /home/BSD.txt > /home/BSD_REPLACE.txt

[root@stapp01 ~]# ls -la /home/BSD_DELETE.txt /home/BSD_REPLACE.txt
-rw-r--r-- 1 root root 8642 Sep 2 10:00 /home/BSD_DELETE.txt
-rw-r--r-- 1 root root 9979 Sep 2 10:00 /home/BSD_REPLACE.txt

[root@stapp01 ~]# echo "Original lines: $(wc -l < /home/BSD.txt)"
Original lines: 169

[root@stapp01 ~]# echo "Lines after delete: $(wc -l < /home/BSD_DELETE.txt)"
Lines after delete: 152

[root@stapp01 ~]# grep "code" /home/BSD_DELETE.txt | wc -l
0

[root@stapp01 ~]# echo "Replacements: $(grep -o '\bfor\b' /home/BSD_REPLACE.txt | wc -l)"
Replacements: 8
Enter fullscreen mode Exit fullscreen mode

Command Explanation

Part A: Delete lines with "code"

grep -v "code" /home/BSD.txt > /home/BSD_DELETE.txt
Enter fullscreen mode Exit fullscreen mode
  • grep -v: Invert match (exclude lines with pattern)
  • "code": Exact case-sensitive match
  • > /home/BSD_DELETE.txt: Redirect output to file

Part B: Replace "from" with "for"

sed -E 's/\bfrom\b/for/g' /home/BSD.txt > /home/BSD_REPLACE.txt
Enter fullscreen mode Exit fullscreen mode
  • -E: Extended regular expressions
  • s/pattern/replacement/g: Substitute globally
  • \b: Word boundary (ensures exact word match)
  • from: Pattern to match (exact word)
  • for: Replacement word
  • g: Replace all occurrences (not just first)

Word Boundary Explanation

\bfrom\b  matches: "from" (standalone word)
\bfrom\b  does NOT match: "fromage", "frolic", "fromula", "fromp"
Enter fullscreen mode Exit fullscreen mode

Verification Commands

# 1. Check files exist
ls -la /home/BSD_DELETE.txt /home/BSD_REPLACE.txt

# 2. Verify no "code" lines in BSD_DELETE.txt
grep "code" /home/BSD_DELETE.txt | wc -l
# Should output: 0

# 3. Verify all "from" are replaced with "for"
grep -o '\bfrom\b' /home/BSD_REPLACE.txt | wc -l
# Should output: 0

# 4. Count how many "for" were added
grep -o '\bfor\b' /home/BSD_REPLACE.txt | wc -l

# 5. Compare line counts
echo "Original: $(wc -l < /home/BSD.txt)"
echo "Deleted: $(wc -l < /home/BSD_DELETE.txt)"
echo "Replaced: $(wc -l < /home/BSD_REPLACE.txt)"

# 6. Check specific lines for proper replacement
grep -n "for" /home/BSD_REPLACE.txt | head -5

# 7. Ensure partial matches weren't affected
grep -E "fromage|frolic|fromula" /home/BSD_REPLACE.txt | head -5
# These should still exist (not affected)
Enter fullscreen mode Exit fullscreen mode

Alternative Methods

Part A: Using sed to delete lines

sed '/code/d' /home/BSD.txt > /home/BSD_DELETE.txt
Enter fullscreen mode Exit fullscreen mode

Part A: Using awk

awk '!/code/' /home/BSD.txt > /home/BSD_DELETE.txt
Enter fullscreen mode Exit fullscreen mode

Part B: Using awk for replacement

awk '{gsub(/\bfrom\b/,"for")}1' /home/BSD.txt > /home/BSD_REPLACE.txt
Enter fullscreen mode Exit fullscreen mode

Part B: Using sed without extended regex

sed 's/\<from\>/for/g' /home/BSD.txt > /home/BSD_REPLACE.txt
Enter fullscreen mode Exit fullscreen mode

Troubleshooting

  1. "No such file or directory":
   # Check if file exists
   ls -la /home/BSD.txt
   # Find alternative location
   find /home -name "BSD.txt" 2>/dev/null
Enter fullscreen mode Exit fullscreen mode
  1. Case sensitivity:
   # If case-insensitive needed (not required here)
   grep -iv "code" /home/BSD.txt > /home/BSD_DELETE.txt
Enter fullscreen mode Exit fullscreen mode
  1. Word boundary not working:
   # Use \< and \> instead of \b
   sed 's/\<from\>/for/g' /home/BSD.txt > /home/BSD_REPLACE.txt
Enter fullscreen mode Exit fullscreen mode
  1. "Permission denied":
   # Use sudo
   sudo grep -v "code" /home/BSD.txt > /home/BSD_DELETE.txt
Enter fullscreen mode Exit fullscreen mode

Complete Script (Run from Jump Host)

#!/bin/bash

echo "========================================="
echo "Processing /home/BSD.txt on App Server 1"
echo "========================================="

ssh tony@stapp01 << 'EOF'
echo 'Ir0nM@n' | sudo -S bash -c '
echo ""
echo "=== Step 1: Part A - Delete lines containing 'code' ==="
grep -v "code" /home/BSD.txt > /home/BSD_DELETE.txt
echo "✓ BSD_DELETE.txt created"

echo ""
echo "=== Step 2: Part B - Replace 'from' with 'for' ==="
sed -E "s/\\bfrom\\b/for/g" /home/BSD.txt > /home/BSD_REPLACE.txt
echo "✓ BSD_REPLACE.txt created"

echo ""
echo "=== Step 3: Verification ==="
echo "Files created:"
ls -la /home/BSD_DELETE.txt /home/BSD_REPLACE.txt

echo ""
echo "Line counts:"
echo "  Original: $(wc -l < /home/BSD.txt)"
echo "  Delete:   $(wc -l < /home/BSD_DELETE.txt)"
echo "  Replace:  $(wc -l < /home/BSD_REPLACE.txt)"

echo ""
echo "Checking for 'code' in BSD_DELETE.txt:"
CODE_COUNT=$(grep -c "code" /home/BSD_DELETE.txt)
if [ "$CODE_COUNT" -eq 0 ]; then
    echo "  ✓ No 'code' lines found"
else
    echo "  ✗ Found $CODE_COUNT 'code' lines"
fi

echo ""
echo "Checking replacements:"
FROM_COUNT=$(grep -o "\\bfrom\\b" /home/BSD.txt | wc -l)
FOR_COUNT=$(grep -o "\\bfor\\b" /home/BSD_REPLACE.txt | wc -l)
echo "  Original 'from': $FROM_COUNT"
echo "  New 'for': $FOR_COUNT"

echo ""
echo "=== Step 4: Sample Output ==="
echo "BSD_DELETE.txt (first 5 lines):"
head -5 /home/BSD_DELETE.txt

echo ""
echo "BSD_REPLACE.txt (first 5 lines):"
head -5 /home/BSD_REPLACE.txt

echo ""
echo "========================================="
echo "✅ Files processed successfully!"
echo "📌 BSD_DELETE.txt: Lines with 'code' removed"
echo "📌 BSD_REPLACE.txt: 'from' replaced with 'for'"
echo "========================================="
'
EOF
Enter fullscreen mode Exit fullscreen mode

Make it executable and run:

chmod +x process_bsd.sh
./process_bsd.sh
Enter fullscreen mode Exit fullscreen mode

Summary

The /home/BSD.txt file has been processed on App Server 1 (stapp01):

  • BSD_DELETE.txt: All lines containing "code" removed
  • BSD_REPLACE.txt: All occurrences of "from" replaced with "for"
  • Word boundaries used: Partial matches not affected
  • Case sensitivity: "code" matches exactly
  • Files created: /home/BSD_DELETE.txt and /home/BSD_REPLACE.txt
  • Verified: No "code" lines remain, all "from" replaced

Both files have been successfully created with the required modifications.

Top comments (0)