With the following script I'm trying to read a text file (italian.txt), and translate from this file all words from Italian into English and save the output in another text file (english.txt). I have to use sed command with the global command g so that I translate every appearance of the word.

It's not working correctly but I don't know what goes wrong. Can somebody help me?

cat italian.txt | sed -i 's/sole/sun/g' | 's/penna/pen/g' > english.txt

exit 0 
  • Maybe a typo, but you're missing sed after the second pipe: cat italian.txt | sed -i 's/sole/sun/g' | sed -i 's/penna/pen/g' > english.txt
    – John N
    Commented Jan 5, 2017 at 11:10
  • You seem to be missing a sed after the second pipe? Commented Jan 5, 2017 at 11:10
  • When executing the script it says sed: no input files. @JohnN
    – Pepka
    Commented Jan 5, 2017 at 11:15
  • 1
    You're using the -i flag to indicate editing files "in place"; however, that requires a file, and you're instead using stdin (the stdout from cat). You can remove the -i (from both seds), and it should work fine.
    – John N
    Commented Jan 5, 2017 at 11:21
  • Yes, it worked! @JohnN Thank you very much!
    – Pepka
    Commented Jan 5, 2017 at 11:23

5 Answers 5


There are a couple of problems with your script:

  1. You need to add a second sed after the second pipe (|).
  2. sed -i tells sed to edit files "in-place", but there is no file specified - sed is using stdin, coming from cat. You can safely remove the -i and your script should now work.

The fixed script should be:

cat italian.txt | sed 's/sole/sun/g' | sed 's/penna/pen/g' > english.txt

You are using it wrong.

First, you don't need cat. sed can take filename to read. Like this:

sed 's/sole/sun/g' italian.txt

Second, you don't need pipe-redirection for next sed-expression. If you need it, it should looks like this:

sed 's/sole/sun/g' italian.txt | sed 's/penna/pen/g' > english.txt

, but it is extra work. sed can process more than one expression. You can split them by «;» or give them to sed as command line arguments with -e before each one.

In sum, command looks so:

sed 's/sole/sun/g; s/penna/pen/g' italian.txt > english.txt

If you had a file with word pairs, for example

sole sun
penna pen

... and so on for many words in Italian and English (there's no practical limit other than memory), then you could create a sed script


... (where \<word\> will match only the word word and not e.g. words or reword) like this:

$ awk '{ printf("s/\\<%s\\>/%s/g\n", $1, $2) }' pairs.txt >translate.sed

Then you could apply that sed script to a text file:

$ sed -f translate.sed italian.txt >english.txt
  • @ Kusalananda, very cool! +1
    – JJoao
    Commented Jan 5, 2017 at 13:31

It's not necessary and redundant to overwrite the contents of italian.txt since the output of sed is being redirected to another file called english.txt and saved anyway. It's also possible to eliminate the useless use of cat

sed -e 's/sole/sun/g' -e 's/penna/pen/g' italian.txt | tee english.txt  
  • sed allows multiple -e switches, which allows replacing more than one thing at a time.
  • tee can be used for data redirection (e.g. to another file called english.txt).

A variant of @Kusalanananda idea:

$ cat dict

$ sed -f <(sed -r 's!(.+):(.+)!s/\\<\1\\>/\2/g!' dict)   it.txt >en.txt

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .