Problems with using tr cmd in bash script. [SOLVED]

Forum rules
Before you post please read how to get help
Post Reply
lazarus
Level 3
Level 3
Posts: 135
Joined: Mon Jul 02, 2018 11:36 pm
Location: Oberon, OZ

Problems with using tr cmd in bash script. [SOLVED]

Post by lazarus » Sat Aug 11, 2018 12:45 am

OK, I've been using a script to replace white spaces in filenames with underscores.

Code: Select all

#!/bin/bash
name=`echo "$@" | sed "s/\ /\_/g"`
mv "$@" $name 
Having come across the tr function, I was delighted & thought I could streamline things using:

Code: Select all

#!/bin/bash
mv "$@" '$(tr " " "_" <<< "$@")'
...but this falls over with an 'unexpected redirect' error. Trying something slightly different, by simply inserting tr in lieu of sed in my 'functional' script:

Code: Select all

#!/bin/bash
name=`echo "$@" | tr " " "_"`
mv "$@" $name 
... it would appear that I'm using tr wrong as this also fails. echo "<text>" | tr " " "_" works fine from console though.

I know I'm missing something obvious, I just can't pick it and the longer I stare the less I'm seeing. :roll:
Last edited by lazarus on Sat Aug 11, 2018 10:27 pm, edited 1 time in total.
- Andy

I may be weird but I'm saving up to become eccentric.

User avatar
catweazel
Level 17
Level 17
Posts: 7114
Joined: Fri Oct 12, 2012 9:44 pm
Location: Australian Antarctic Territory

Re: Problems with using tr cmd in bash script.

Post by catweazel » Sat Aug 11, 2018 1:06 am

lazarus wrote:
Sat Aug 11, 2018 12:45 am
... it would appear that I'm using tr wrong as this also fails. echo "<text>" | tr " " "_" works fine from console though.

I know I'm missing something obvious, I just can't pick it and the longer I stare the less I'm seeing. :roll:
It's possible that bash is expanding " " "_". What happens if you use single quotes?

echo "<text>" | tr ' ' '_'
¡uʍop ǝpısdn sı buıɥʇʎɹǝʌǝ os ɐıןɐɹʇsnɐ ɯoɹɟ ɯ,ı

lazarus
Level 3
Level 3
Posts: 135
Joined: Mon Jul 02, 2018 11:36 pm
Location: Oberon, OZ

Re: Problems with using tr cmd in bash script.

Post by lazarus » Sat Aug 11, 2018 2:29 am

Yep. You've put your finger on the problem; my scripts aren't evaluating correctly.

I've tried a few different things - including changing quotes - but I just cannot get the lines incorporating the tr cmd to return the string I expect/want.

Perhaps a good nap will change things. :|

In the meantime, the sed version works well. I've no real need to replace it except that in an idle moment I was house-keeping... and ran face first into a brick wall.
- Andy

I may be weird but I'm saving up to become eccentric.

User avatar
xenopeek
Level 24
Level 24
Posts: 22772
Joined: Wed Jul 06, 2011 3:58 am
Location: The Netherlands

Re: Problems with using tr cmd in bash script.

Post by xenopeek » Sat Aug 11, 2018 5:58 am

The pure bash way with parameter expansion to substitute all spaces with underscores:

Code: Select all

#!/bin/bash
mv "$@" "${@// /_}"
Mind that "$@" joins all arguments to the script with single spaces. This is likely not what you want. Say you have a file called hello world.c, calling your script as myscript hello world.c will do as you expect. But if for some reason there are not one but two spaces between "hello" and "world.c", your script will fail. You could fix this by quoting or escaping the filename, like myscript "hello world.c" or "myscript hello\ \ world.c, but be mindful that this makes it look like you could pass multiple filenames to the script like myscript "hello world.c" "foo bar.c" "hoity toity.c" but that will of course also not work (because ${@} merges all arguments into one string).

Anyway, while Bash manual says you can use character classes in parameter expansion substitution—that doesn't work here. So I can't use mv "$@" "${@//[:space:]/_}" to catch all types of whitespace (space, tab, newline; whitespace characters that could also be in filenames and you'd want to have replaced by underscores).

With tr that does work. Here's the same as above with tr but with using character class to catch all whitespace:

Code: Select all

#!/bin/bash
mv "$@" "$(echo -n "$@" | tr '[:space:]' '_')"
Image

blockhead47
Level 2
Level 2
Posts: 80
Joined: Wed Jun 15, 2016 4:50 pm
Location: Chicago, IL, USA

Re: Problems with using tr cmd in bash script.

Post by blockhead47 » Sat Aug 11, 2018 10:22 am

This is how I have done the same thing:

Code: Select all

#!/bin/bash
#
    printf "\n\tRemoving spaces from --->ALL<--- file names in current path $(pwd)\n\n"
    printf "\t"
    read -p "Press Enter to continue (Ctrl-C to quit) " junk
    find . -type f | while read i
    do
        mv -v "$i" "${i// /_}" 2>/dev/null
    done

lazarus
Level 3
Level 3
Posts: 135
Joined: Mon Jul 02, 2018 11:36 pm
Location: Oberon, OZ

Re: Problems with using tr cmd in bash script.

Post by lazarus » Sat Aug 11, 2018 10:26 pm

As I tend to only write minimal scripts, character classes are one of those things I've always wondered about but never needed to use. I can see now where they'd be very handy indeed!

Although I am slightly ashamed that I didn't think of mv "$@" "${@// /_}" for myself... obviously I have much to learn.

Thanks for the help, people, and many thanks for the reasoning, Xeno. That helps. A lot. :)
- Andy

I may be weird but I'm saving up to become eccentric.

Post Reply

Return to “Scripts & Bash”