My old code was:
let comps = split(str, { $0 == "-" || $0 == " " }, maxSplit: Int.max, allowEmptySlices: false)
after update of Swift 2 my XCode 7 fix it to:
let comps = split(str.characters, { $0 == "-" || $0 == " " }, maxSplit: Int.max, allowEmptySlices: false).map { String($0) }
but now I have an error: Cannot invoke 'map' with an argument list of type '((_) -> _)'
How to fix it.
Link to old answer on Swift
The order of arguments for split() function messed up for some reason. It should be:
let comps = split(str.characters, maxSplit: Int.max, allowEmptySlices: false) {
$0 == "-" || $0 == " "
}.map {
String($0)
}
Related
Compare two strings and find mismatch and mismatch and count them both
string1 = "SEQUENCE"
string2 = "SEKUEAEE"
I want output like. With the mismatch and match count.
'SS' match 1
'EE' match 3
'UU' match 1
'QK' mismatch 1
'NA' mismatch 1
'CE' mismatch 1
Here's a solution in old Perl. Also works with however many strings you want
use warnings;
use strict;
use List::AllUtils qw( mesh part count_by pairs );
my #strings = ("SEQUENCES", "SEKUEAEES", "SEKUEAEES");
my $i = 0;
print join "",
map { $_->[0] . " " . ($_->[1] > 1 ? 'match' : 'mismatch') . " " . $_->[1] ."\n" }
pairs
count_by { $_ }
map { join "", #$_ }
part { int($i++/scalar #strings) }
&mesh( #{[ map { [ split // ] } #strings ]} )
;
And here for comparison, analogous code in Perl 6.
my #strings = "SEQUENCES", "SEKUEAEES", "SEKUEAEES";
([Z] #strings>>.comb)
.map({ .join })
.Bag
.map({ "{.key} { .value > 1 ?? 'match' !! 'mismatch' } {.value}\n" })
.join
.say;
Isn't that just pretty?
Solution that works for any amount of strings.
use List::Util qw(max);
use Perl6::Junction qw(all);
my #strings = qw(SEQUENCE SEKUEAEE);
my (%matches, %mismatches);
for my $i (0 .. -1 + max map { length } #strings) {
my #c = map { substr $_, $i, 1 } #strings;
if ($c[0] eq all #c) {
$matches{join '', #c}++;
} else {
$mismatches{join '', #c}++;
}
}
for my $k (keys %matches) {
printf "'%s' match %d\n", $k, $matches{$k};
}
for my $k (keys %mismatches) {
printf "'%s' mismatch %d\n", $k, $mismatches{$k};
}
__END__
'SS' match 1
'UU' match 1
'EE' match 3
'QK' mismatch 1
'NA' mismatch 1
'CE' mismatch 1
Useing the non-core but very handy List::MoreUtils module.
#!/usr/bin/env perl
use warnings;
use strict;
use feature qw/say/;
use List::MoreUtils qw/each_array/;
sub count_matches {
die "strings must be equal length!" unless length $_[0] == length $_[1];
my #letters1 = split //, $_[0];
my #letters2 = split //, $_[1];
my (%matches, %mismatches);
my $iter = each_array #letters1, #letters2;
while (my ($c1, $c2) = $iter->()) {
if ($c1 eq $c2) {
$matches{"$c1$c2"} += 1;
} else {
$mismatches{"$c1$c2"} += 1;
}
}
say "'$_' match $matches{$_}" for sort keys %matches;
say "'$_' mismatch $mismatches{$_}" for sort keys %mismatches;
}
count_matches qw/SEQUENCE SEKUEAEE/;
I was trying to combine the two lines.
example of my data is ::
Hello Reach World Test
Reach me Test out .
I would like to combine this as ::
Output
Hello Reach World Test Reach me Test out .i.e Only if last word matches Test and Begin matches Reach .
I was trying with
awk '/Test$/ { printf("%s\t", $0); next } 1' .
Could anyone please let me know how to match it and combine.
Does this awk script do what you want:
BEGIN { flag = "0"; line = "" }
{
if ( flag == "1" ) {
if ( $0 ~ "^Reach" )
print line " " $0
else {
print line
print $0
}
line = ""
flag = "0"
} else {
if ( $0 ~ "Test$" ) {
line = $0
flag = "1"
} else
print $0
}
}
I am writing a program that is heavily dependent on the perl's index function to take strings. My objective so to break this string into a series of substrings that do not have any spaces.
The problem that I am having is that in the second half of the loop the index function starts skipping spaces.
I am using the test data:
1 12 a 2 5 P Q
I am expecting to get:
1, 12, a, 2, 5, P, Q,
Instead I get:
1, 12, a, 2 5, P Q,
My code follows:
use 5.010;
use strict;
use warnings;
my $ivalue = <stdin>;
chomp($ivalue);
$ivalue = $ivalue . " ";
my $current;
my $space = 0;
my $safespace = 0;
my $lastspace = 0;
my $closestspace = 0;
my $i = 0;
# Test data - 1 12 a 2 5 P Q
while ($space != -1){
$space = index($ivalue, " ", $space + $i++);
$closestspace = $space - $lastspace;
#print $lastspace . " " . $space . " = " . $closestspace . "; ";
$current = substr($ivalue, $lastspace, $closestspace);
#say "substring = " . $current;
$lastspace = $space + 1;
}
Thanks ahead of time! If anyone has any suggestion on how to improve the way I asked my question or on my code in general those are appreciated as well.
The problem is in this line:
$space = index($ivalue, " ", $space + $i++);
instead of using $i, make that $space + 1
I have a shell script that is doing something.I want to print the Unknown string where there is blank space in the output.
I want to do check if (f[1] == "") or (f[2] == "") or (f[3] == ""), it should be replaced by a unknown string and should be written in a single file
if(f[1] == "") printf(fmt, id, f[1], f[2], f[3]) > file
where f[1],f[2],f[3] if empty should be replaced by unknown string
where f[1] is the first index, fmt is the format specifier I have defined in the code.How to replace these empty spaces with a string in Linux.
Any lead is appreciated.
Thanks
Use the conditional operator:
ec2-describe-instances | awk -F'\t' -v of="$out" -v mof="$file" '
function pr() { # Print accumulated data
if(id != "") { # Skip if we do not have any unprinted data.
printf(fmt, id, f[1], f[2], f[3]) > of
if (f[1] == "" || f[2] == "" || f[3] == "") {
printf(fmt, id, f[1]==""?"Unknown":f[1], f[2]==""?"Unknown":f[2], f[3]==""?"Unknown":f[3]) > mof
}
}
# Clear accumulated data.
id = f[1] = f[2] = f[3] = ""
}
BEGIN { # Set the printf() format string for the header and the data lines.
fmt = "%-20s %-40s %-33s %s\n"
# Print the header
headerText="Instance Details"
headerMaxLen=100
padding=(length(headerText) - headerMaxLen) / 2
printf("%" padding "s" "%s" "%" padding "s" "\n\n\n", "", headerText, "") > of
printf(fmt, "Instance id", "Name", "Owner", "Cost.centre") > of
printf("%" padding "s" "%s" "%" padding "s" "\n\n\n", "", headerText, "") > mof
printf(fmt, "Instance id", "Name", "Owner", "Cost.centre") > mof
}
$1 == "TAG" {
# Save the Instance ID.
id = $3
if($4 ~ /[Nn]ame/) fs = 1 # Name found
else if($4 ~ /[Oo]wner/) fs = 2 # Owner found
else if($4 ~ /[Cc]ost.[Cc]ent[er][er]/) fs = 3 # Cost center found
else next # Ignore other TAGs
f[fs] = $5 # Save data for this field.
}
$1 == "RESERVATION" {
# First line of new entry found; print results from previous entry.
pr()
}
END { # EOF found, print results from last entry.
pr()
}'
I have this code, but it's giving me an error
awk '
FNR == NR {
# reading get_ids_only.txt
values[$1] = ""
next
}
BEGIN {
# reading default.txt
for (elem in values){
if ($0 ~ elem){
if (values[elem] == ""){
values[elem] = "\"" $0 "\""
getline;
values[elem] = "\n"" $0 ""\n"
}
else{
values[elem] = values[elem] ", \"" $0 "\""
getline;
values[elem] = values[elem] "\n"" $0 ""\n"
}
}
}
END {
for (elem in values)
print elem " [" values[elem] "]"
}
' get_ids_only.txt default.txt
The error says
awk: syntax error at source line 23
context is
>>> END <<< {
awk: illegal statement at source line 24
awk: illegal statement at source line 24
missing }
This is where my END{ } function starts...
What I'm trying to do is.. compare the string.... in file 1.. if the string is found in file 2, print the string and print the line after it as well., then skip a space.
input1:
message id "hello"
message id "good bye"
message id "what is cookin"
input2:
message id "hello"
message value "greetings"
message id "good bye"
message value "limiting"
message id "what is there"
message value "looking for me"
message id "what is cooking"
message value "breakfast plate"
output:
should print out all the input1, grabbing the message value from input 2.
can anyone guide me on why this error is occurring?
I'm using the terminal on my mac.
Here's your BEGIN block with recommended indention and comments, can you see the problem?
BEGIN {
# reading default.txt
for (elem in values){
if ($0 ~ elem){
if (values[elem] == ""){
values[elem] = "\"" $0 "\""
getline;
values[elem] = "\n"" $0 ""\n"
}
else{
values[elem] = values[elem] ", \"" $0 "\""
getline;
values[elem] = values[elem] "\n"" $0 ""\n"
} # End inner if
} # End outer if
} # End for loop
Your missing a closing brace. Note that in the final concatenation with $0, $0 is actually quoted.
There are some other issues with this, I'm not sure what you are trying to do, but it seems a very un-awky approach. Usually if you find yourself overusing getline, you should be thinking about spreading the code into separate blocks with appropriate conditions. See this article on the uses an misuses of getline for more.
A more awky way to solve it
If I understand you correctly, this is the way I would solve this task:
extract.awk
FNR==NR { id[$0]; next } # Collect id lines in the `id' array
$0 in id { f=1 } # Use the `f' as a printing flag
f # Print when `f' is 1
NF==0 { f=0 } # Stop printing after an empty line
Run it like this:
awk -f extract.awk input1 input2
Output:
message id "hello"
message value "greetings"
message id "good bye"
message value "limiting"