1

I need to replace the following characters:

ă with a

â with a

î with i

ș with s

ț with t

The replacement must be case sensitive. For example if a letter is upper-case then it must be replaced with an upper-case letter.

I've read that I could use sed for this process but I don't know how to use it. Can anyone help me by writing the exact command that I must run in Terminal?

  • See also echo ă â î ș ț | iconv -t us//TRANSLIT which outputs a ^a ^i s t on OS/X (and a a i s t on GNU). – Stéphane Chazelas Jan 19 '16 at 12:19
3

Even though sed is commonly used for these types of tasks, it isn't actually designed for them—its very name is stream editor.

The tool that is designed for non-interactive file editing is ex. (vi is the "visual editor" form of ex.) Particularly when you want to edit files in place, ex is a far superior tool to sed.

In this case the commands used are almost identical to the sed command given earlier, but they don't have to be. The following is POSIX compliant (unlike sed -i).

for file in *.php; do ex -sc '%s/[ăâ]/a/ge | %s/ș/s/ge | %s/ț/t/ge | %s/î/i/ge | x' "$file" ; done

Explanation:

-s starts "silent mode" in preparation for batch processing. -c specifies the command(s) to be executed.

% means to apply the following command to every line in the file. The s/// commands are fairly self-explanatory; the e flag at the end means that any errors (due to the pattern not being found) are suppressed and file processing will continue.

| is a command separator (not a pipe).

x tells ex to write any changes to the file (but only if there were changes) and exit.


If you want in-place file editing, ex is the tool of choice. If you want to preview the changes before you make them, I'd recommend using tr as @gardenhead suggests.

(Of course, if you're using a proper version control system such as git, you could make the changes in place using ex and compare the files to the old version by running git diff.)

  • Have later discovered, the e flag to the s command is not specified in POSIX. – Wildcard Mar 11 '16 at 4:33
4

sed will work, but this is much simpler with tr, which translates characters.

for file in *.php; do tr 'ăâîșțĂÂÎȘȚ' 'aaistaaist' < "${file}" > "translated_${file}"

The sed equivalent (which you'll need on GNU systems, not OS/X where tr doesn't support multibyte characters) would be:

sed 'y/ăâîșțĂÂÎȘȚ/aaistaaist/'
  • @Stephane, confused by the parenthetical statement. Does GNU tr support multibyte characters, or does OS X tr support multibyte characters? It seems that you're saying OS X tr doesn't, but that sed is only needed on GNU systems—which doesn't make sense. – Wildcard Mar 14 '16 at 23:37
1

You can replace the characters using the formula sed s/old_string/new_string/.

From manpage:

sed - stream editor for filtering and transforming text

s/regexp/replacement/
              Attempt to match regexp against the pattern space.  If successful, replace that  portion  matched  with
              replacement.   The replacement may contain the special character & to refer to that portion of the pat‐
              tern space which matched, and the special escapes \1 through \9 to refer to the corresponding  matching
              sub-expressions in the regexp.

If you've set of characters to replace, then I recommend creating file (e.g. replace.sed) containing the definition of replacement as follows:

$ cat replace.sed
s/ă/a/g
s/â/a/g
s/î/i/g
s/ș/s/g
s/ț/t/g

And then run you can execute as follows:

  • sed -f replace.sed < old.php > new.php

    Which replace characters specified in replace.sed with new-ones from old.php and output to new.php

  • sed -i -f replace.sed file.php

    Which replace file.php simultaneously replacing characters specified in replace.sed

    From manpage:

    -i[SUFFIX], --in-place[=SUFFIX]
    
                  edit files in place (makes backup if SUFFIX supplied)
    

Or you can define simultaneously in a line like:

sed -e 's/ă/a/g' -e 's/â/a/g' -e 's/î/i/g' -e 's/ș/s/g' -e 's/ț/t/g'

For doing this operation for all .php files, you can use something like:

  • find . -name "*.php" -exec sed -i '' -f replace.sed '{}' \;
  • for i in *.php; do sed -i '' -f replace.sed "$i"; done

Note: Use -maxdepth 1 with find to limit for locating *.php in current directory only. Visit man sed for more information.

  • Isn't this last s (-e 's/ș/s') expression incomplete? – Kira Jan 18 '16 at 15:44
  • @Kira see revised post – Pandya Jan 18 '16 at 15:50
  • And how can I make it go through all the files inside a specific folder? – Andrei Jan 18 '16 at 16:02
  • @Andrei see revised post. Note that -i option with sed will replace the old files – Pandya Jan 18 '16 at 16:17
  • 1
    sed has a y command for transliteration. – Stéphane Chazelas Jan 19 '16 at 12:21
0

If you prefer a GUI tool, you can try jEdit. It has excellent search and replace functionality, including folder (directory) search. You can use regular expressions if you like. Hypersearch pops up a separate window with the results.

jEdit search

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.