15

I have a variable that is entered at a prompt:

my $name = <>;

I want to append a fixed string '_one'to this (in a separate variable).

E.g. if $name = Smith then it becomes 'Smith_one'

I have tried several various ways which do not give me the right results, such as:

my $one = "${name}_one";

^ The _one appears on the next line when I print it out and when I use it, the _one is not included at all.

Also:

my $one = $name."_one";

^ The '_one' appears at the beginning of the string.

And:

my $end = '_one';
my $one = $name.$end;
or 
my $one = "$name$end";

None of these produce the result I want, so I must be missing something related to how the input is formatted from the prompt, perhaps. Ideas appreciated!

2 Answers 2

34

Your problem is unrelated to string appending: When you read a line (e.g. via <>), then the record input separator is included in that string; this is usually a newline \n. To remove the newline, chomp the variable:

    my $name = <STDIN>; # better use explicit filehandle unless you know what you are doing
    # now $name eq "Smith\n"
    chomp $name;
    # now $name eq "Smith"

To interpolate a variable into a string, you usually don't need the ${name} syntax you used. These lines will all append _one to your string and create a new string:

    "${name}_one"  # what you used
    "$name\_one"   # _ must be escaped, else the variable $name_one would be interpolated
    $name . "_one"
    sprintf "%s_one", $name
    # etc.

And this will append _one to your string and still store it in $name:

    $name .= "_one"
Sign up to request clarification or add additional context in comments.

3 Comments

ahhh that is interesting about the newline character - chomp immediately solves the problem! I'd tried those methods of appending, too, with no luck - but now they all work! Thanks!
Funny; I was thinking how much better to use "${name}_one" than awkward constructs like "$name\_one" or $name . "_one".
@JonathanLeffler Thank you for your edit. By now, I'm also in the “${foo} is clear syntax, not an anachronistic bash-ism” camp, and that my original suggestions were worse. I've edited accordingly.
0

Thanks - that's really helpful. In case it helps anyone else trying to fix / set the date modified of files downloaded from Google Photos or via WhatsApp (which strips all the exif data), I used the following:

This will work with WhatsApp type stuff in the format 'IMG-20170721-WA0009.jpg', and set hours, mins and seconds to 01 01 01

find . -name \* | perl -lne 'my $a=$_; s/[^\d]+(\d{4})(\d{2})(\d{2})-.*/$1$2$3/ && print "touch -t ${_}0101.01\ \"${a}\"" '

this fixes images like '20170721_063856.jpg'

find . -name \* | perl -lne 'my $a=$_; s/.*(\d{4})(\d{2})(\d{2})_(\d{2})(\d{2})(\d{2}).*/$1$2$3$4$5.$6/ && print "touch -t $_\ \"$a\"" '
  • and again just add the | bash -x to get it to actually execute. Those search an entire directory, in case you're looking for videos / non-jpgs too

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.