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

About writing shell scripts and making the most of your shell
Forum rules
Topics in this forum are automatically closed 6 months after creation.
Locked
lazarus

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

Post by lazarus »

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 LockBot on Wed Dec 28, 2022 7:16 am, edited 2 times in total.
Reason: Topic automatically closed 6 months after creation. New replies are no longer allowed.
User avatar
catweazel
Level 19
Level 19
Posts: 9763
Joined: Fri Oct 12, 2012 9:44 pm
Location: Australian Antarctic Territory

Re: Problems with using tr cmd in bash script.

Post by catweazel »

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 ' ' '_'
"There is, ultimately, only one truth -- cogito, ergo sum -- everything else is an assumption." - Me, my swansong.
lazarus

Re: Problems with using tr cmd in bash script.

Post by lazarus »

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.
User avatar
xenopeek
Level 25
Level 25
Posts: 29507
Joined: Wed Jul 06, 2011 3:58 am

Re: Problems with using tr cmd in bash script.

Post by xenopeek »

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 3
Level 3
Posts: 140
Joined: Wed Jun 15, 2016 4:50 pm

Re: Problems with using tr cmd in bash script.

Post by blockhead47 »

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

Re: Problems with using tr cmd in bash script.

Post by lazarus »

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. :)
Locked

Return to “Scripts & Bash”