1

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 Jan 5 '17 at 11:10
  • You seem to be missing a sed after the second pipe? – Ulrich Schwarz Jan 5 '17 at 11:10
  • When executing the script it says sed: no input files. @JohnN – Pepka Jan 5 '17 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 Jan 5 '17 at 11:21
  • Yes, it worked! @JohnN Thank you very much! – Pepka Jan 5 '17 at 11:23
6

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
4

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
2

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

s/\<sole\>/sun/g
s/\<penna\>/pen/g

... (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 Jan 5 '17 at 13:31
1

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).
0

A variant of @Kusalanananda idea:

$ cat dict
sole:sun
penna:pen

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

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.