Trying to do sorting in redis with the following command:
sort ids by messages|*->ss ASC LIMIT 0 10 GET messages|*->ss ALPHA
messages|.ss is string value
output:
1 that of
a community in
add ensuring so #this should be at the end before b...
against entitled and #this should be at the end before b...
a give and
a he can
a objective world
a of like
a to I
birthday moment daily
As you can see whitespaces are ignored. I'm expecting those lines to be at the end before "birthday moment daily"
add ensuring so
against entitled and
Tried to set LC_ALL=C and LC_COLLATE=C environment variables, didn't help.
redis 3.0.0
CentOS 6.5
Related
I am trying to store a Google geocode lookup as a variable in BASH.
Here's what I want to end up with
(or something similar to it)
_GEOINFO=$(curl "http://maps.googleapis.com/maps/api/geocode/json?address="$_WHERE""
Here's what almost works:
_CITY="Grand rapids"
_STATE="Michigan"
_COUNTRY="United States of America"
_WHERE="\"$_CITY\",\"$_STATE\",\"$_COUNTRY\""
curl "http://maps.googleapis.com/maps/api/geocode/json?address="$_WHERE""
Here's what doesn't:
curl "http://maps.googleapis.com/maps/api/geocode/json?address=$_WHERE"
I've tried so many different variations on escaaping:
\"$_WHERE\", \'\"$_WHERE\"\', \"${_WHERE}\",
For most things I've tried, I get an error saying:
parse error: Invalid numeric literal at line 1, column 10
FIXED IT!
# store location information into variables
_CITY="Grand rapids"
_STATE="Michigan"
_COUNTRY="United States of America"
# store all information as one string
_WHERE="$_CITY,$_STATE,$_COUNTRY"
# replace spaces with a +
_WHERE="${_WHERE// /+}"
# store the geo-location information into a variable
_GEOINFO=$(curl "http://maps.googleapis.com/maps/api/geocode/json?address=\"$_WHERE\""
The following code is something I am beginning to test for use within a "Texas Hold Em" style game I am working on.
My question is why, when running the following code, does the puts involving a "♥" return a "\u" in it's place. I feel certain it is this multibyte character that is causing the issue becuse on the second puts , I replaced the ♦ with a d in the array of strings and it returned what i was expecting. See Below:
My Code:
#! /usr/bin/env ruby
# encoding: utf-8
table_cards = ["|2♥|", "|8♥|", "|6d|", "|6♣|", "|Q♠|"]
# Array of cards
player_1_face_1 = "8"
player_1_suit_1 = "♦"
# Player 1's face and suit of first card he has
player_1_face_2 = "6"
player_1_suit_2 = "♥"
# Player 1's face and suit of second card he has
test_str_1 = /(\D8\D{2})/.match(table_cards.to_s)
# EX: Searching for match between face values on (player 1's |8♦|) and the |8♥| on the table
test_str_2 = /(\D6\D{2})/.match(table_cards.to_s)
# EX: Searching for match between face values on (player 1's |6♥|) and the |6d| on the table
puts "#{test_str_1}"
puts "#{test_str_2}"
Puts to Screen:
|8\u
|6d|
-- My goal would be to get the first puts to return: |8♥|
I am not so much looking for a solution to this (there may not even be one) but more so a "as simple as possible" explanation of what is causing this issue and why. Thanks ahead of time for any information on what is happening here and how I can tackle the goal.
The "\u" you're seeing is the Unicode string indicator.
For example, Unicode character 'HEAVY BLACK HEART' (U+2764) can be printed as "\u2764".
A friendly Unicode character listing site is http://unicode-table.com/en/sets/
Are you able to launch interactive Ruby in your shell and print a heart like this?
irb
irb> puts "\u2764"
❤
When I run your code in my Ruby, I get the answer you expect:
test_str_1 = /(\D8\D{2})/.match(table_cards.to_s)
=> #<MatchData "|8♥|" 1:"|8♥|">
What happens if you try a regex that is more specific to your cards?
test_str_1 = /(\|8[♥♦♣♠]\|)/.match(table_cards.to_s)
In your example output, you're not seeing the Unicode heart symbol as you want. Instead, your output is printing the "\u" which is the Unicode starter, but then not printing the rest of the expected string which is "2764".
See the comment by the Tin Man that describes encoding for your console. If he's correct, then I expect the more-specific regex will succeed, but still print the wrong output.
See the comment by David Knipe that says it looks like it gets truncated because the regex only matches 4 characters. If he's correct, then I expect the more-specific regex will succeed and also print the right output.
(The rest of this answer is typical for Unix; if you're on Windows, ignore the rest here...)
To show your system language settings, try this in your shell:
echo $LC_ALL
echo $LC_CTYPE
If they are not "UTF-8" or something like that, try this in your shell:
export LC_ALL=en_US.UTF-8
export LC_CTYPE=en_US.UTF-8
Then re-run your code -- be sure to use the same shell.
If this works, and you want to make this permanent, one way is to add these here:
# /etc/environment
LC_ALL=en_US.UTF-8
LC_CTYPE=en_US.UTF-8
Then source that file from your .bashrc or .zshrc or whatever shell startup file you use.
Preferably awk but other scripting ok. ("{{{1" on line ends are for vim folding and should be irrelevant to the desired output.) The data in the example comes from online chatrooms, that I pasted into a text file.
Begin file contents:
-----------------------------------------------
/mysql unauth'd user on show processlist, plus db conn error in a site {{{1
1:05
Gary
can you ck belljar20 instance?
1:06
Justin looks like reverse dns issue
-----------------------------------------------
/mysql pingtimes to db server solved by adding domain to /etc/hosts on db server {{{1
per internal wiki
...
-----------------------------------------------
/php54 back to php52 with manual fix for https {{{1
Gary
can u force mkp44aaa.net to bind to an ip address?
...
-----------------------------------------------
:End file contents
The records, aka blocks (of varying numbers of lines) start with a one word "/category" as the first word of the first line, after a beginning forward slash "/", and end with a line of about 40 dashes. Above, in the 3 block examples, are two with category "/mysql" and one with category "php54".
In the example above I would like the output to have been sorted so the two "/mysql" category blocks are next to each other in the sorted output.
So, essentially, just sort the blocks by the category name.
I've seen lots of components of a solution but just cannot seem to find one that is on point enough for me to adapt it.
If you can use perl:
#! /bin/bash
input=/tmp/file
perl -n0le '
while (s/(\/\w+(.|\n)*?-+)//m){
$str=$1; $str=~/(\/\w+)/;
$h{$1}=[] unless exists $h{$1};
push #{h{$1}},$str;
}
END{
foreach $key (sort keys %h){
foreach ( #{$h{$key}} ){
print $_."\n";
}
}
}' $input
Explanation:
There's a lot of things going on there, first of all we want a multi-line match, that's why we're using -0 which puts the whole content of the input file into $_.
Then we want extract our pattern "(\/\w+(.|\n)*?-+)" create a hash of arrays with key being "/category". At end we sort based on that key and print.
Output:
bash test.sh
/aaa
this is a test
-----------------------------------------------
/mysql unauth'd user on show processlist, plus db conn error in a site {{{1
1:05
Gary
can you ck belljar20 instance?
1:06
Justin looks like reverse dns issue
-----------------------------------------------
/mysql pingtimes to db server solved by adding domain to /etc/hosts on db server {{{1
per internal wiki
...
-----------------------------------------------
/php54 back to php52 with manual fix for https {{{1
Gary
can u force mkp44aaa.net to bind to an ip address?
...
-----------------------------------------------
I'm trying to write a blog post about the dangers of having a common access point name.
So I did some wardriving to get a list of access point names, and I downloaded a list of the 1000 most common access point names (which there exists rainbow tables for) from Renderlab.
But how can I compare those two text files, to see how many of my collected access point names that are open to attacks from rainbow tables?
The text files are build like this:
collected.txt:
linksys
internet
hotspot
Most common access point names are called
SSID.txt:
default
NETGEAR
Wireless
WLAN
Belkin54g
So the script should sort the lines, compare them and show how many times the lines from collected.txt are found in SSID.txt ..
Does that make any sense? Any help would be grateful :)
If you don't mind using python script:
file1=open('collected.txt', 'r') # open file 1 for reading
with open('SSID.txt', 'r') as content_file: # ready file 2
SSID = content_file.read()
found={} # summary of found names
for line in file1:
if line in SSID:
if line not in found:
found[line]=1
else:
found[line]+=1
for i in found:
print found[i], i # print out list and no. of occurencies
...it can be run in the dir containing these files - collected.txt and SSID.txt - it will return a list looking like this:
5 NETGEAR
3 default
(...)
Script reads file 1 line-by line and compares it to the whole file 2. It can be easily modified to take file names from command prompt.
First, take a look on a simple tutorial about sdiff command, like How do I Compare two files under Linux or UNIX. Also, Notepad++ support this.
To find the number of times each line in file A appears in file B, you can do:
awk 'FNR==NR{a[$0]=1; next} $0 in a { count[$0]++ }
END { for( i in a ) print i, count[i] }' A B
If you want the output sorted, pipe the output to sort, but there's no need to sort just to find the counts. Note that the $0 in a clause can be omitted at the cost of consuming more memory, which may be a problem if file B is very large.
I've written a little Ruby script that requires some user input. I anticipate that users might be a little lazy at some point during the data entry where long entries are required and that they might cut and paste from another document containing newlines.
I've been playing with the Highline gem and quite like it. I suspect I am just missing something in the docs but is there a way to get variable length multiline input?
Edit: The problem is that the newline terminates that input and the characters after the newline end up as the input for the next question.
Here's what the author uses in his example: (from highline-1.5.0/examples)
#!/usr/local/bin/ruby -w
# asking_for_arrays.rb
#
# Created by James Edward Gray II on 2005-07-05.
# Copyright 2005 Gray Productions. All rights reserved.
require "rubygems"
require "highline/import"
require "pp"
grades = ask( "Enter test scores (or a blank line to quit):",
lambda { |ans| ans =~ /^-?\d+$/ ? Integer(ans) : ans} ) do |q|
q.gather = ""
end
say("Grades:")
pp grades
General documentation on HighLine::Question#gather (from highline-1.5.0/lib/highline/question.rb)
# When set, the user will be prompted for multiple answers which will
# be collected into an Array or Hash and returned as the final answer.
#
# You can set _gather_ to an Integer to have an Array of exactly that
# many answers collected, or a String/Regexp to match an end input which
# will not be returned in the Array.
#
# Optionally _gather_ can be set to a Hash. In this case, the question
# will be asked once for each key and the answers will be returned in a
# Hash, mapped by key. The <tt>#key</tt> variable is set before each
# question is evaluated, so you can use it in your question.
#
attr_accessor :gather
These seem to be your main options w/in the library. Anything else, you'd have to do yourself.
Wouldn't it be something like:
input.gsub!('\r\n', '')