Re: Add Quotes to entries in a file
by choroba (Cardinal) on Jul 12, 2018 at 13:12 UTC
|
perl -pe 's/;/";"/g; s/";"/;"/; s/"$//' input > output
The first substitution wraps each semicolon in double quotes. The second one removes the double quotes before the first semicolon, the third one removes the last double quote.
To copy the file, you can also use Path::Tiny's copy or File::Copy's copy or cp.
($q=q:Sq=~/;[c](.)(.)/;chr(-||-|5+lengthSq)`"S|oS2"`map{chr |+ord
}map{substrSq`S_+|`|}3E|-|`7**2-3:)=~y+S|`+$1,++print+eval$q,q,a,
| [reply] [d/l] [select] |
|
|
Delightfully clever, turning the statement of the problem on its head to create an elegant solution.
| [reply] |
Re: Add Quotes to entries in a file
by Tux (Canon) on Jul 12, 2018 at 15:27 UTC
|
But, but, but, what if any of those fields is already quoted? And what if that field contains a ;?
use Text::CSV_XS "csv";
csv (in => csv (in => *DATA, sep => ";"), sep => ";", quote_always =>
+1, out => \my $out);
print $out =~ s/^"([^"]*)"/$1/grm;
__END__
ABC;123;;;;;HELLO;
DEF;345;;BANANA;12DEF;44,55;4*12;;;;;;;;3;
-->
$ perl test.pl
ABC;"123";"";"";"";"";"HELLO";""
DEF;"345";"";"BANANA";"12DEF";"44,55";"4*12";"";"";"";"";"";"";"";"3";
+""
Enjoy, Have FUN! H.Merijn
| [reply] [d/l] [select] |
|
|
| [reply] [d/l] [select] |
Re: Add Quotes to entries in a file
by hippo (Archbishop) on Jul 12, 2018 at 13:13 UTC
|
use strict;
use warnings;
use Test::More tests => 2;
my @rec = (
{
have => 'ABC;123;;;;;HELLO;',
want => 'ABC;"123";"";"";"";"";"HELLO";'
},
{
have => 'DEF;345;;BANANA;12DEF;44,55;4*12;;;;;;;;3;',
want => 'DEF;"345";"";"BANANA";"12DEF";"44,55";"4*12";"";"";""
+;"";"";"";"";"3";'
}
);
for my $this (@rec) {
$this->{have} =~ s/;/";"/g;
$this->{have} =~ s/";/;/;
$this->{have} =~ s/;"$/;/;
is ($this->{have}, $this->{want})
}
I have a sneaking suspicion that the goalposts may be about to move. Let's hope not. | [reply] [d/l] |
Re: Add Quotes to entries in a file
by johngg (Canon) on Jul 12, 2018 at 18:05 UTC
|
A solution using split, a single substitution on an array slice then a join.
johngg@abouriou ~/perl/Monks $ perl -Mstrict -Mwarnings -E '
open my $inFH, q{<}, \ <<__EOD__ or die $!;
ABC;123;;;;;HELLO;
DEF;345;;BANANA;12DEF;44,55;4*12;;;;;;;;3;
__EOD__
my $outFile = do { \ my $dummy; };
open my $outFH, q{>}, $outFile or die $!;
while ( <$inFH> )
{
my @items = split m{;};
s{(.*)}{"$1"} for @items[ 1 .. ( $#items - 1 ) ];
print $outFH join q{;}, @items;
}
print $$outFile;'
ABC;"123";"";"";"";"";"HELLO";
DEF;"345";"";"BANANA";"12DEF";"44,55";"4*12";"";"";"";"";"";"";"";"3";
I hope this is of interest.
| [reply] [d/l] |
|
|
No substitution is necessary since you're just wrapping double-quotes around strings. Also, in the pure-string version, a split LIMIT of -1 is needed to capture a final empty | empty string field for later re-join-ing; in the file-based version, the final field is a newline, which gets very neatly join-ed back on.
c:\@Work\Perl\monks>perl -wMstrict -le
"my @strings = (
'ABC;123;;;;;HELLO;',
'DEF;345;;BANANA;12DEF;44,55;4*12;;;;;;;;3;',
);
;;
for my $s (@strings) {
printf qq{'$s' \n>};
my @items = split m{;}, $s, -1;
$_ = qq{\"$_\"} for @items[ 1 .. ( $#items - 1 ) ];
print join(q{;}, @items), qq{< \n};
}
"
'ABC;123;;;;;HELLO;'
>ABC;"123";"";"";"";"";"HELLO";<
'DEF;345;;BANANA;12DEF;44,55;4*12;;;;;;;;3;'
>DEF;"345";"";"BANANA";"12DEF";"44,55";"4*12";"";"";"";"";"";"";"";"3"
+;<
Give a man a fish: <%-{-{-{-<
| [reply] [d/l] [select] |
Re: Add Quotes to entries in a file
by AnomalousMonk (Archbishop) on Jul 12, 2018 at 15:09 UTC
|
FWIW, a single-regex solution:
c:\@Work\Perl\monks>perl -wMstrict -le
"use Test::More 'no_plan';
use Test::NoWarnings;
;;
my @vectors = (
[ 'ABC;123;;;;;HELLO;' =>
q{ABC;'123';'';'';'';'';'HELLO';}
],
[ 'DEF;345;;BANANA;12DEF;44,55;4*12;;;;;;;;3;' =>
q{DEF;'345';'';'BANANA';'12DEF';'44,55';'4*12';'';'';'';'';'';'';
+'';'3';}
],
);
;;
for my $ar_vector (@vectors) {
my ($string, $expected) = @$ar_vector;
(my $got = $string) =~ s{ (?<= ;) ([^;]*) (?= ;) }{'$1'}xmsg;
is $got, $expected, qq{'$string' -> \n >$expected<};
}
"
ok 1 - 'ABC;123;;;;;HELLO;' ->
# >ABC;'123';'';'';'';'';'HELLO';<
ok 2 - 'DEF;345;;BANANA;12DEF;44,55;4*12;;;;;;;;3;' ->
# >DEF;'345';'';'BANANA';'12DEF';'44,55';'4*12';'';'';'';'';'';'';'';
+'3';<
ok 3 - no warnings
1..3
Notes:
-
Run under Win7, Perl version 5.8.9.
-
Single-quotes were used in the example code instead of doubles because Windoze command-line escaping would have made the cut-paste unreadable. Substitute double-quotes for single-quotes in the replacement of the substitution to address original problem.
-
The /r modifier for a s/// substitution added with Perl version 5.14 makes the code slightly simpler (tested):
my $got = $string =~ s{ (?<= ;) ([^;]*) (?= ;) }{'$1'}xmsgr;
(See s/// in perlop.)
Update: The regex used above has also been tested and works not only with "pure" strings (i.e., with nothing after the final semicolon), but with test strings ending in a newline after the final semicolon, as would be presumed to be the case for strings read from a file.
Give a man a fish: <%-{-{-{-<
| [reply] [d/l] [select] |
Re: Add Quotes to entries in a file
by jwkrahn (Abbot) on Jul 12, 2018 at 18:38 UTC
|
$ echo "ABC;123;;;;;HELLO;
DEF;345;;BANANA;12DEF;44,55;4*12;;;;;;;;3;" | perl -lpe's/;\K([^;]*)/"
+$1"/g'
ABC;"123";"";"";"";"";"HELLO";""
DEF;"345";"";"BANANA";"12DEF";"44,55";"4*12";"";"";"";"";"";"";"";"3";
+""
| [reply] [d/l] |
|
|
| [reply] [d/l] [select] |
Re: Add Quotes to entries in a file
by niseus (Initiate) on Jul 12, 2018 at 14:11 UTC
|
@chobra
when i try your line i just get Can't find string terminator "'" anywhere before EOF at -e line 1. Im probally doing something wrong but im just beginning with pearl so bear with me :)
@hippo
Would that work if i had different files with different content?
| [reply] |
|
|
| [reply] [d/l] [select] |
|
|
Are you on MSWin? Quoting is different there, single quotes don't work. Have you used copy/paste or retyped the command? Also note that @name doesn't work on PerlMonks. To get the author alerted about a reply, reply to their node.
($q=q:Sq=~/;[c](.)(.)/;chr(-||-|5+lengthSq)`"S|oS2"`map{chr |+ord
}map{substrSq`S_+|`|}3E|-|`7**2-3:)=~y+S|`+$1,++print+eval$q,q,a,
| [reply] [d/l] |
|
|
Hi,
i now did it with " instead if ' but now all it does is copy my File in a new one but no quotes are added.
| [reply] |
|
|
| [reply] |
|
|
| [reply] [d/l] |