Create a text encoding conversion service in Automator

automatorcommand lineencodingfinderterminal

I was trying to make a Finder service to easily convert text encoding of some files. Because the default charset for Simplified Chinese in Windows is the Chinese national standard GB18030 (not the UTF-8 used on Mac).

With some help from the answers at services – Automator Get Filename of Selected File – Ask Different, I set up Service receives selected: Files or folders in:Finder

Then, I made this Shell script in Automator:

for f in "$@"
do
    iconv -f gb18030 -t utf-8 f > f.new
done

However, when I run the service when selecting f, I don't see the newly created f.new in Finder. I guess I have set the output path wrong. But I don't know what is the right way to fix it.

Automator screenshot

Best Answer

Change:

for f in "$@"
do
    iconv -f gb18030 -t utf-8 f > f.new
done

To:

for f in "$@"; do
    if [[ ! $(basename "$f") =~ .*\..* ]]; then
        iconv -f gb18030 -t utf-8 < "$f" > "${f}-new"
    else
        iconv -f gb18030 -t utf-8 < "$f" > "${f%.*}-new.${f##*.}"
    fi
done

And set Pass input: to as arguments on the Run Shell Script action.


To address the comment made by Gordon Davisson to handle a filename with no extension, I've modified the code in my answer above.

The code tests the filename portion of the fully qualified pathname passed to the Run Sell Script action using a regex to see if it has an extension, or more literally a . as part of the filename, and if there is no . in the filename it process the if branch, otherwise it processes the else branch.

Also note that using a glob instead of a regex, e.g.:

if [[ ! $(base name "$f") == *.* ]]; then

Would also work to test for an extension. Either way the new fully qualified pathname will appropriately follow one of these two examples:

  • /path/to/filename becomes: /path/to/filename-new
  • /path/to/filename.ext becomes: /path/to/filename-new.ext

Note: This answer assumes fully qualified pathnames do not contain null characters and or carriage returns and or linefeeds. IMO Proper pathnames do not contains such characters and I will not test for them.