I have this simple piece of code here:
foreach my $key (keys %$structure)
{
$key =~ s/\r?$//;
$structure->{$key} =~ s/\r?$//;
}
This is a part of my trimming function, which takes in a reference to an object. This object (a hash, in our case) was previously initialized from the keyboard.
The problem is that each typed argument has an \r at the end, which is not very cool for outputting the structure. And even though I'm trying to substitute the \r with a regex, it just won't work. Why is that?
$str =~ s/\r//g; Carriage returns and linefeeds are removed by combining \r and \n in that order, of course, since that's the order in which they appear in text files, like those that are created on Windows systems.
CR = Carriage Return ( \r , 0x0D in hexadecimal, 13 in decimal) — moves the cursor to the beginning of the line without advancing to the next line.
$ perl -pe 's/\cM\cJ?//g' input 1,2,3 4,5,6,7,8,9 10,11,12 Making the \cJ optional handles the case when a file ends with ctrl-M but not ctrl-J. Only do this if you want to combine a line with the next. This removes all carriage returns and all newlines. This will join only lines with a carriage return at the end of the line to the next line.
Another module, one that provides all the 3 function is Text::Trim , but it take the Perl-ish writing a step further, and maybe to slightly dangerous places. If you call it and use the return value in a print statement or assign it to a variable, it will return the trimmed version of the string and will keep the original intact.
We can convert line breaks in a text file from Unix format (Line feed) to DOS format (carriage return + Line feed) and vice versa: cat input | tr -d '' > output tr -d '' < input > output cat -v output od -c output Perl is yet another method to remove all the carriage returns from a file in Unix or Linux systems. The syntax is:
Perl is yet another method to remove all the carriage returns from a file in Unix or Linux systems. The syntax is: The col command filters out reverse (and half reverse) line feeds so that the output is in the correct order with only forward and half-forward line feeds and replaces white-space characters with tabs where possible.
It's easier to use chomp the keyboard input and then use that value as a key rather than modify a key of a hash later on. If you're using STDIN in the same script than save the STDIN to a variable and wrap that in a chomp.
chomp($variable = <STDIN>);
Then use the variable as a key.
The chomp function answers your question
chomp $key
...
https://www.geeksforgeeks.org/perl-chomp-function/
You have a few syntactical errors and you also don't delete the old $key
.
Something like this should work:
foreach my $key (keys %structure) {
my $value = $structure{$key};
delete $structure{$key};
$key =~ s/\r$//;
$structure{$key} = $value;
}
Alternatively:
%structure = map { $a = $structure{$_}; s/\r$//; $_ => $a } keys %structure;
As other answers have stated chomp
removes the trailing newline character. It also works on hashes, i.e., chomp(%some_hash)
removes the newline character of every value of that hash. It does not change the keys.
EDIT: It also chomps every element of an array. So you can do this:
perl -MData::Dumper -e 'my %hey = ("a\n" => "b\n", "c\n" => "d");
chomp(my @a = %hey); %hey = (@a); print Dumper(\%hey)'
$VAR1 = {
'c' => 'd',
'a' => 'b'
};
This might be resource intensive if the hash is large. And "\r"
is not chomp
ed on all systems. I recommend iterating over the hash and using s
(or chop
if every key and value ends with "\r"
) as a better solution.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With