'Bash command runs from command line but not from within a script [closed]

Under WSL (Ubuntu), I use this command to extract the From: line from a folder of .eml files:

for f in *.eml; do echo -oe | grep "^From" < "$f" | sed -e "s/From://g" >> emails.txt; done

Works great. However, if I put that same command in a bash script, it fails with this message:

/bin/bash: for f in *.eml; do echo -oe | grep "^From" < "$f" | sed -e "s/From://g" >> emails.txt; done: No such file or directory

Please tell me why. Thanks.

Edit: Below is the script, which resides in home/jim/bin (which is in the path) and is run from the directory containing the .eml files.

#!/bin/bash
for f in *.eml; do echo -oe | grep "^From" < "$f" | sed -e "s/From://g" >> emails.txt; done


Solution 1:[1]

There's no need for the loop. You can simply give all the filenames to sed

#!/bin/bash
sed -n '/^From:/s/^From: //p' *.eml >> emails.txt

Solution 2:[2]

Your script should work fine. In general, what works on the command line works in scripts, too (except aliases and job control and similar facilities for interactive use).

However, you will want to avoid the useless grep. Try this instead.

#!/bin/sh
for f in *.eml; do
    sed -n '/^From: */!d;s///p;q' "$f"
done >> emails.txt

It's not at all clear what you hoped the echo would do. This simply reads up through the first From: line and prints it, then stops reading from that input file.

This assumes that all your *.eml files are well-formed, i.e. contain a From: header.

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1 Barmar
Solution 2