Friday, February 27, 2009
Wednesday, February 25, 2009
Show biggest files/directories, biggest first with 'k,m,g' eyecandy
Thursday, February 19, 2009
10 Awk Tips, Tricks and Pitfalls
This article takes a look at ten tips, tricks and pitfalls in Awk programming language. They are mostly taken from the discussions in #awk IRC channel. Here they are:
- 1. Be idiomatic!
- 2. Pitfall: shorten pipelines
- 3. Print lines using ranges
- 4. Split file on patterns
- 5. Locale-based pitfalls
- 6. Parse CSV
- 7. Pitfall: validate an IPv4 address
- 8. Check whether two files contain the same data
- 9. Pitfall: contexts and variable types in awk
- 10. Pulling out things
Be idiomatic!
In this paragraph, we give some hints on how to write more idiomatic (and usually shorter and more efficient) awk programs. Many awk programs you’re likely to encounter, especially short ones, make large use of these notions.
Suppose one wants to print all the lines in a file that match some pattern (a kind of awk-grep, if you like). A reasonable first shot is usually something like
awk '{if ($0 ~ /pattern/) print $0}'
That works, but there are a number of things to note.
The first thing to note is that it is not structured according to the awk’s definition of a program, which is
condition { actions }
Our program can clearly be rewritten using this form, since both the condition and the action are very clear here:
awk '$0 ~ /pattern/ {print $0}'
Our next step in the perfect awk-ification of this program is to note that /pattern/ is the same as $0 ~ /pattern/. That is, when awk sees a single regular expression used as an expression, it implicitly applies it to $0, and returns success if there is a match. Then we have:
awk '/pattern/ {print $0}'
Now, let’s turn our attention to the action part (what’s inside braces). print $0 is a redundant statement, since print alone, by default, prints $0.
awk '/pattern/ {print}'
But now we note that, when it finds that a condition is true, and there are no associated actions, awk performs a default action that is (you guessed it) print (which we already know is equivalent to print $0). Thus we can do this:
awk '/pattern/'
Now we have reduced the initial program to its simplest (and more idiomatic) form. In many cases, if all you want to do is print some lines, according to a condition, you can write awk programs composed only of a condition (although complex):
awk '(NR%2 && /pattern/) || (!(NR%2) && /anotherpattern/)'
That prints odd lines that match /pattern/, or even lines that match /anotherpattern/. Naturally, if you don’t want to print $0 but instead do something else, then you’ll have to manually add a specific action to do what you want.
From the above, it follows that
awk 1
awk '"a"' # single quotes are important!
are both awk programs that just print their input unchanged. Sometimes, you want to operate only on some lines of the input (according to some condition), but also want to print all the lines, regardless of whether they were affected by your operation or not. A typical example is a program like this:
awk '{sub(/pattern/,"foobar")}1'
This tries to replace “pattern” with “foobar“. Whether or not the substitution succeeds, the always-true condition “1” prints each line (you could even use “42″, or “19″, or any other nonzero value if you want; “1″ is just what people traditionally use). This results in a program that does the same job as sed ’s/pattern/foobar/’. Here are some examples of typical awk idioms, using only conditions:
awk 'NR % 6' # prints all lines except those divisible by 6
awk 'NR > 5' # prints from line 6 onwards (like tail -n +6, or sed '1,5d')
awk '$2 == "foo"' # prints lines where the second field is "foo"
awk 'NF >= 6' # prints lines with 6 or more fields
awk '/foo/ && /bar/' # prints lines that match /foo/ and /bar/, in any order
awk '/foo/ && !/bar/' # prints lines that match /foo/ but not /bar/
awk '/foo/ || /bar/' # prints lines that match /foo/ or /bar/ (like grep -e 'foo' -e 'bar')
awk '/foo/,/bar/' # prints from line matching /foo/ to line matching /bar/, inclusive
awk 'NF' # prints only nonempty lines (or: removes empty lines, where NF==0)
awk 'NF--' # removes last field and prints the line
awk '$0 = NR" "$0' # prepends line numbers (assignments are valid in conditions)
Another construct that is often used in awk is as follows:
awk 'NR==FNR { # some actions; next} # other condition {# other actions}' file1 file2
This is used when processing two files. When processing more than one file, awk reads each file sequentially, one after another, in the order they are specified on the command line. The special variable NR stores the total number of input records read so far, regardless of how many files have been read. The value of NR starts at 1 and always increases until the program terminates. Another variable, FNR, stores the number of records read from the current file being processed. The value of FNR starts from 1, increases until the end of the current file, starts again from 1 as soon as the first line of the next file is read, and so on. So, the condition “NR==FNR” is only true while awk is reading the first file. Thus, in the program above, the actions indicated by “# some actions” are executed when awk is reading the first file; the actions indicated by “# other actions” are executed when awk is reading the second file, if the condition in “# other condition” is met. The “next” at the end of the first action block is needed to prevent the condition in “# other condition” from being evaluated, and the actions in “# other actions” from being executed while awk is reading the first file.
There are really many problems that involve two files that can be solved using this technique. Here are some examples:
# prints lines that are both in file1 and file2 (intersection)
awk 'NR==FNR{a[$0];next} $0 in a' file1 file2
Here we see another typical idiom: a[$0] has the only purpose of creating the array element indexed by $0. During the pass over the first file, all the lines seen are remembered as indexes of the array a. The pass over the second file just has to check whether each line being read exists as an index in the array a (that’s what the condition $0 in a does). If the condition is true, the line is printed (as we already know).
Another example. Suppose we have a data file like this
20081010 1123 xxx
20081011 1234 def
20081012 0933 xyz
20081013 0512 abc
20081013 0717 def
...thousand of lines...
where “xxx”, “def”, etc. are operation codes. We want to replace each operation code with its description. We have another file that maps operation codes to human readable descriptions, like this:
abc withdrawal
def payment
xyz deposit
xxx balance
...other codes...
We can easily replace the opcodes in the data file with this simple awk program, that again uses the two-files idiom:
# use information from a map file to modify a data file
awk 'NR==FNR{a[$1]=$2;next} {$3=a[$3]}1' mapfile datafile
First, the array a, indexed by opcode, is populated with the human readable descriptions. Then, it is used during the reading of the second file to do the replacements. Each line of the datafile is then printed after the substitution has been made.
Another case where the two-files idiom is useful is when you have to read the same file twice, the first time to get some information that can be correctly defined only by reading the whole file, and the second time to process the file using that information. For example, you want to replace each number in a list of numbers with its difference from the largest number in the list:
# replace each number with its difference from the maximum
awk 'NR==FNR{if($0>max) max=$0;next} {$0=max-$0}1' file file
Note that we specify “file file” on the command line, so the file will be read twice.
Caveat: all the programs that use the two-files idiom will not work correctly if the first file is empty (in that case, awk will execute the actions associated to NR==FNR while reading the second file). To correct that, you can reinforce the NR==FNR condition by adding a test that checks that also FILENAME equals ARGV[1].
Pitfall: shorten pipelines
It’s not uncommon to see lines in scripts that look like this:
somecommand | head -n +1 | grep foo | sed 's/foo/bar/' | tr '[a-z]' '[A-Z]' | cut -d ' ' -f 2
This is just an example. In many cases, you can use awk to replace parts of the pipeline, or even all of it:
somecommand | awk 'NR>1 && /foo/{sub(/foo/,"bar"); print toupper($2)}'
It would be nice to collect here many examples of pipelines that could be partially or completely eliminated using awk.
Print lines using ranges
Yes, we all know that awk has builtin support for range expressions, like
# prints lines from /beginpat/ to /endpat/, inclusive
awk '/beginpat/,/endpat/'
Sometimes however, we need a bit more flexibility. We might want to print lines between two patterns, but excluding the patterns themselves. Or only including one. A way is to use these:
# prints lines from /beginpat/ to /endpat/, not inclusive
awk '/beginpat/,/endpat/{if (!/beginpat/&&!/endpat/)print}'
# prints lines from /beginpat/ to /endpat/, not including /beginpat/
awk '/beginpat/,/endpat/{if (!/beginpat/)print}'
It’s easy to see that there must be a better way to do that, and in fact there is. We can use a flag to keep track of whether we are currently inside the interesting range or not, and print lines based on the value of the flag. Let’s see how it’s done:
# prints lines from /beginpat/ to /endpat/, not inclusive
awk '/endpat/{p=0};p;/beginpat/{p=1}'
# prints lines from /beginpat/ to /endpat/, excluding /endpat/
awk '/endpat/{p=0} /beginpat/{p=1} p'
# prints lines from /beginpat/ to /endpat/, excluding /beginpat/
awk 'p; /endpat/{p=0} /beginpat/{p=1}'
All these programs just set p to 1 when /beginpat/ is seen, and set p to 0 when /endpat/ is seen. The crucial difference between them is where the bare “p” (the condition that triggers the printing of lines) is located. Depending on its position (at the beginning, in the middle, or at the end), different parts of the desired range are printed. To print the complete range (inclusive), you can just use the regular /beginpat/,/endpat/ expression or use the flag technique, but reversing the order of the conditions and associated patterns:
# prints lines from /beginpat/ to /endpat/, inclusive
awk '/beginpat/{p=1};p;/endpat/{p=0}'
It goes without saying that while we are only printing lines here, the important thing is that we have a way of selecting lines within a range, so you can of course do anything you want instead of printing.
Split file on patterns
Suppose we have a file like this
line1
line2
line3
line4
FOO1
line5
line6
FOO2
line7
line8
FOO3
line9
line10
line11
FOO4
line12
FOO5
line13
We want to split this file on all the occurrences of lines that match /^FOO/, and create a series of files called, for example, out1, out2, etc. File out1 will contain the first 4 lines, out2 will contain “line5″ and “line6″, etc. There are at least two ways to do that with awk:
# first way, works with all versions of awk
awk -v n=1 '/^FOO[0-9]*/{close("out"n);n++;next} {print > "out"n}' file
Since we don’t want to print anything when we see /^FOO/, but only update some administrative data, we use the “next” statement to tell awk to immediately start processing the next record. Lines that do not match /^FOO/ will instead be processed by the second block of code. Note that this method will not create empty files if an empty section is found (eg, if “FOO5\nFOO6″ is found, the file “out5″ will not be created). The “-v n=1” is used to tell awk that the variable “n” should be initialized with a value of 1, so effectively the first output file will be called “out1“.
Another way (which however needs GNU awk to work) is to read one chunk of data at a time, and write that to its corresponding out file.
# another way, needs GNU awk
LC_ALL=C gawk -v RS='FOO[0-9]*\n' -v ORS= '{print > "out"NR}' file
The above code relies on the fact that GNU awk supports assigning a regular expression to RS (the standard only allows a single literal character or an empty RS). That way, awk reads a series of “records”, separated by the regular expression matching /FOO[0-9]*\n/ (that is, the whole FOO… line). Since newlines are preserved in each section, we set ORS to empty since we don’t want awk to add another newline at the end of a block. This method does create an empty file if an empty section is encountered. On the downside, it’s a bit fragile because it will produce incorrect results if the regex used as RS appears somewhere else in the rest of the input.
We will see other examples where gawk’s support for regexes as RS is useful. Note that the last program used LC_ALL=C at the beginning…
Locale-based pitfalls
Sometimes awk can behave in an unexpected way if the locale is not C (or POSIX, which should be the same). See for example this input:
-rw-r--r-- 1 waldner users 46592 2003-09-12 09:41 file1
-rw-r--r-- 1 waldner users 11509 2008-10-07 17:42 file2
-rw-r--r-- 1 waldner users 11193 2008-10-07 17:41 file3
-rw-r--r-- 1 waldner users 19073 2008-10-07 17:45 file4
-rw-r--r-- 1 waldner users 36332 2008-10-07 17:03 file5
-rw-r--r-- 1 waldner users 33395 2008-10-07 16:53 file6
-rw-r--r-- 1 waldner users 54272 2008-09-18 16:20 file7
-rw-r--r-- 1 waldner users 20573 2008-10-07 17:50 file8
You’ll recognize the familiar output of ls -l here. Let’s use a non-C locale, say, en_US.utf8, and try an apparently innocuous operation like removing the first 3 fields.
$ LC_ALL=en_US.utf8 awk --re-interval '{sub(/^([^[:space:]]+[[:space:]]+){3}/,"")}1' file
-rw-r--r-- 1 waldner users 46592 2003-09-12 09:41 file1
-rw-r--r-- 1 waldner users 11509 2008-10-07 17:42 file2
-rw-r--r-- 1 waldner users 11193 2008-10-07 17:41 file3
-rw-r--r-- 1 waldner users 19073 2008-10-07 17:45 file4
-rw-r--r-- 1 waldner users 36332 2008-10-07 17:03 file5
-rw-r--r-- 1 waldner users 33395 2008-10-07 16:53 file6
-rw-r--r-- 1 waldner users 54272 2008-09-18 16:20 file7
-rw-r--r-- 1 waldner users 20573 2008-10-07 17:50 file8
It looks like sub() did nothing. Now change that to use the C locale:
$ LC_ALL=C awk --re-interval '{sub(/^([^[:space:]]+[[:space:]]+){3}/,"")}1' file
users 46592 2003-09-12 09:41 file1
users 11509 2008-10-07 17:42 file2
users 11193 2008-10-07 17:41 file3
users 19073 2008-10-07 17:45 file4
users 36332 2008-10-07 17:03 file5
users 33395 2008-10-07 16:53 file6
users 54272 2008-09-18 16:20 file7
users 20573 2008-10-07 17:50 file8
Now it works. Another localization issue is the behavior of bracket expressions matching, like for example [a-z]:
$ echo 'èòàù' | LC_ALL=en_US.utf8 awk '/[a-z]/'
èòàù
This may or may not be what you want. When in doubt or when facing an apparently inexplicable result, try putting LC_ALL=C before your awk invocation.
Parse CSV
This is another thing people do all the time with awk. Simple CSV files (with fields separated by commas, and commas cannot appear anywhere else) are easily parsed using FS=’,’. There can be spaces around fields, and we don’t want them, like eg
field1 , field2 , field3 , field4
Exploiting the fact that FS can be a regex, we could try something like FS=’^ *| *, *| *$’. This can be problematic for two reasons:
- actual data field might end up correponding either to awk’s fields 1 … NF or 2 … NF, depending on whether the line has leading spaces or not;
- for some reason, assigning that regex to FS produces unexpected results if fields have embedded spaces (anybody knows why?).
In this case, it’s probably better to parse using FS=’,’ and remove leading and trailing spaces from each field:
# FS=','
for(i=1;i<=NF;i++){
gsub(/^ *| *$/,"",$i);
print "Field " i " is " $i;
}
Another common CSV format is
"field1","field2","field3","field4"
Assuming double quotes cannot occur in fields. This is easily parsed using FS=’^”|”,”|”$’ (or FS=’”,”|”‘ if you like), keeping in mind that the actual fields will be in position 2, 3 … NF-1. We can extend that FS to allow for spaces around fields, like eg
"field1" , "field2", "field3" , "field4"
by using FS=’^ *”|” *, *”|” *$’. Usable fields will still be in positions 2 … NF-1. Unlike the previous case, here that FS regex seems to work fine. You can of course also use FS=’,’, and remove extra characters by hand:
# FS=','
for(i=1;i<=NF;i++){
gsub(/^ *"|" *$/,"",$i);
print "Field " i " is " $i;
}
Another CSV format is similar to the first CSV format above, but allows for field to contain commas, provided that the field is quoted:
field1, "field2,with,commas" , field3 , "field4,foo"
We have a mixture of quoted and unquoted fields here, which cannot parsed directly by any value of FS (that I know of, at least). However, we can still get the fields using match() in a loop (and cheating a bit):
$0=$0","; # yes, cheating
while($0) {
match($0,/[^,]*,| *"[^"]*" *,/);
sf=f=substr($0,RSTART,RLENGTH); # save what matched in sf
gsub(/^ *"?|"? *,$/,"",f); # remove extra stuff
print "Field " ++c " is " f;
sub(sf,""); # "consume" what matched
}
As the complexity of the format increases (for example when escaped quotes are allowed in fields), awk solutions become more fragile. Although I should not say this here, for anything more complex than the last example, I suggest using other tools (eg, Perl just to name one). Btw, it looks like there is an awk CSV parsing library here: http://lorance.freeshell.org/csv/ (I have not tried it).
Pitfall: validate an IPv4 address
Let’s say we want to check whether a given string is a valid IPv4 address (for simplicity, we limit our discussion to IPv4 addresses in the traditiona dotted quad format here). We start with this seemingly valid program:
awk -F '[.]' 'function ok(n){return (n>=0 && n<=255)} {exit (ok($1) && ok($2) && ok($3) && ok($4))}'
This seems to work, until we pass it ‘123b.44.22c.3′, which it happily accepts as valid. The fact is that, due to the way awk’s number to string conversion works, some strings may “look like” numbers to awk, even if we know they are not. The correct thing to do here is to perform a string comparison against a regular expression:
awk -F '[.]' 'function ok(n) {
return (n ~ /^([01]?[0-9]?[0-9]|2[0-4][0-9]|25[0-5])$/)
}
{exit (ok($1) && ok($2) && ok($3) && ok($4))}'
Check whether two files contain the same data
We want to check whether two (unsorted) files contain the same data, that is, the set of lines of the first file is the same set of lines of the second file. One way is of course sorting the two files and processing them with some other tool (for example, uniq or diff). But we want to avoid the relatively expensive sort operation. Can awk help us here? The answer (you guessed it) is yes. If we know that the two files do not contain duplicates, we can do this:
awk '!($0 in a) {c++;a[$0]} END {exit(c==NR/2?0:1)}' file1 file2
and check the return status of the command (0 if the files are equal, 1 otherwise). The assumption we made that the two files must not contain duplicate lines is crucial for the program to work correctly. In essence, what it does is to keep track of the number of different lines seen. If this number is exactly equal to half the number of total input records seen, then the two files must be equal (in the sense described above). To understand that, just realize that, in all other cases (ie, when a file is only a partial subset or is not a subset of the other), the total number of distinct lines seen will always be greater than NR/2.
The program’s complexity is linear in the number of input records.
Pitfall: contexts and variable types in awk
We have this file:
1,2,3,,5,foo
1,2,3,0,5,bar
1,2,3,4,5,baz
and we want to replace the last field with “X” only when the fourth field is not empty. We thus do this:
awk -F ',' -v OFS=',' '{if ($4) $6="X"}1'
But we see that the substitution only happens in the last line, instead of the last two as we expected. Why?
Basically, there are only two data types in awk: strings and numbers. Internally, awk does not assign a fixed type to the variables; they are literally considered to be of type “number” and “string” at the same time, with the number 0 and the null string being equivalent. Only when a variable is used in the program, awk automatically converts it to the type it deems appropriate for the context. Some contexts strictly require a specific type; in that case, awk automatically converts the variable to that type and uses it. In contexts that does not require a specific type, awk treats variables that “look like” numbers as numbers, and the other variables are treated as strings. In out example above, the simple test “if ($4)” does not provide a specific context, since the tested variable can be anything. In the first line, $4 is an empty string, so awk considers it false for the purposes of the test. In the second line, $4 is “0″. Since it look like a number, awk uses it like a number, ie zero. Since 0 is considered false, the test is unsuccessful and the substitution is not performed.
Luckily, there is a way to help awk and tell it exactly what we want. We can use string concatenation and append an empty string to the variable (which does not change its value) to explicitly tell awk that we want it to treat it like a string, or, conversely, add 0 to the variable (again, without changing its value) to explicitly tell awk that we want a number. So this is how our program should be to work correctly:
awk -F ',' -v OFS=',' '{if ($4"") $6="X"}1' # the "" forces awk to evaluate the variable as a string
With this change, in the second line the if sees the string “0″, which is not considered false, and the test succeeds, just as we wanted.
As said above, the reverse is also true. Another typical problematic program is this:
awk '/foo/{tot++} END{print tot}'
This, in the author’s intention, should count the number of lines that match /foo/. But if /foo/ does not appear in the input, the variable tot retains its default initial value (awk initializes all variables with the dual value “” and 0). print expects a string argument, so awk supplies the value “”. The result is that the program prints just an empty line. But we can force awk to treat the variable as numeric, by doing this:
awk '/foo/{tot++} END{print tot+0}'
The seemingly innocuous +0 has the effect of providing numeric context to the variable “tot“, so awk knows it has to prefer the value 0 of the variable over the other possible internal value (the empty string). Then, numeric-to-string conversion still happens to satisfy print, but this time what awk converts to string is 0, so print sees the string “0″ as argument, and prints it.
Note that, if an explicit context has been provided to a variable, awk remembers that. That can lead to unexpected results:
# input: 2.5943 10
awk '{$1=sprintf("%d",$1); # truncates decimals, but also explicitly turns $1 into a string!
if($1 > $2) print "something went wrong!" } # this is printed
Here, after the sprintf(), awk notes that we want $1 to be a string (in this case, “2″). Then, when we do if($1>$2), awk sees that $2 has no preferred type, while $1 does, so it converts $2 into a string (to match the wanted type of $1) and does a string comparison. Of course, 99.9999% of the times this is not what we want here. In this case, the problem is easily solved by doing “if ($1+0 > $2)” (doing $2+0 instead WON’T work!), doing “$1=$1+0” after the sprintf(), or using some other means to truncate the value of $1, that does not give it explicit string type.
Pulling out things
Suppose you have a file like this:
Yesterday I was walking in =the street=, when I saw =a
black dog=. There was also =a cat= hidden around there. =The sun= was shining, and =the sky= was blue.
I entered =the
music
shop= and I bought two CDs. Then I went to =the cinema= and watched =a very nice movie=.
End of the story.
Ok, silly example, fair enough. But suppose that we want to print only and all the parts of that file that are like =something=. We have no knowledge of the structure of the file. The parts we’re interested in might be anywere; they may span lines, or there can be many of them on a single line. This seemingly daunting and difficult task is actually easily accomplished with this small awk program:
awk -v RS='=' '!(NR%2)'
# awk -v RS='=' '!(NR%2){gsub(/\n/," ");print}' # if you want to reformat embedded newlines
Easy, wasn’t it? Let’s see how this works. Setting RS to ‘=’ tells awk that records are separated by ‘=’ (instead of the default newline character). If we look at the file as a series of records separated by ‘=’, it becomes clear that what we want are the even-numbered records. So, just throw in a condition that is true for even-numbered records to trigger the printing.
GNU awk can take this technique a step further, since it allows us to assign full regexes to RS, and introduces a companion variable (RT) that stores the part of the input that actually matched the regex in RS. This allows us, for example, to apply the previous technique when the interesting parts of the input are delimited by different characters or string, like for example when we want everything that matches
gawk -v RS='?tag>' 'RT==""'
or again
gawk -v RS='?tag>' '!(NR%2)'
and be done with that. Another nice thing that can be done with GNU awk and RT is printing all the parts of a file that match an arbitrary regular expression (something otherwise usually not easily accomplished). Suppose that we want to print everything that looks like a number in a file (simplifiying, here any sequence of digits is considered a number, but of course this can be refined), we can do just this:
gawk -v RS='[0-9]+' 'RT{print RT}'
Checking that RT is not null is necessary because for the last record of a file RT is null, and an empty line would be printed in that case. The output produced by the previous program is similar to what can be obtained using grep -o. But awk can do better than that. We can use a slight variation of this same technique if we want to add context to our search (something grep -o alone cannot do). For example, let’s say that we want to print all numbers, but only if they appear inside “–”, eg like –1234–, and not otherwise. With gawk, we can do this:
gawk -v RS='--[0-9]+--' 'RT{gsub(/--/,"",RT);print RT}'
So, a carefully crafted RS selects only the “right” data, that can be subsequently extracted safely and printed.
With non-GNU awk, matching all occurrences of an expression can still be done, it just requires more code. See FindAllMatches.
Have fun!
Have fun learning Awk! It’s a fun language to know.
Ps. I will go silent for a week. I have an on-site interview with Google in Mountain View, California. I’ll be back on 31st of October and will post something new in the first week of November!
Did you like this post? Subscribe here:
If you really enjoyed the post, I'd appreciate a gift from my geeky Amazon book wishlist. Books would make make me more educated and I would write even better posts. Thanks! :)
Related Posts
- Update on Famous Awk One-Liners Explained
- Famous Awk One-Liners Explained, Part III
- Famous Awk One-Liners Explained, Part II
- Set Operations in the Unix Shell Simplified
- Set Operations in the Unix Shell
- Famous Awk One-Liners Explained, Part I
- Golfing the Extraction of IP Addresses from ifconfig
- Revisiting GNU Awk YouTube Video Downloader
- Traffic Accounting with Linux IPTables
- Solving Google Treasure Hunt Puzzle 4: Prime Numbers
29 Responses
Wednesday, February 18, 2009
S60 第三版简介及部分技巧
1、S60 第三版简介
Symbian 9.0 加上 S60 第三版的系统,Symbians60 OS V9.1等手机已经不同以往的 Symbian 手机,以往 S60使用的软件,现在都必需有 Symbian 的认证才可以安装,所以以往自行开发的软件都不能再装到 Symbians60 OS V9.1手机里去,必需重新编译才行。即使是小小的抓屏幕软件也是一样.
S60 第三版是建置在 Symbian OS V9.1 之上,也改变了一些重要程序,Symbian C++开发者就必需了解这一环才可以开发新软件。每个新版本的 S60 平台通常都会有一长串的新功能,也让这些应用程序可以顺利被开发,而第三版的S60 平台也是如此。然而第三版有的是一些基础性的程序变动,这将影响之前支持 S60的各式软件的安装或执行。其中两个重大改变就是编辑器的大改版,这是对 S60程序开发者影响最大的一部份,另一个就是平台系统的安全性功能的增加。
S60 第三版包含 .sis 档案的程序托管程序,这代表之后所有的 .sis 档案必需经过合法的认证才可以安装到 Symbian手机里,而且第三版之前的版本软件也不可再安装到第三版的手机里,这个称为 "Symbian signed 认证" 以后都将成为Symbian 手机应用程序所需的官方认证,不论是第三版或之后的版本。另外还有一个「Symbian开发者认证」对于软件开发者也是同等需要的。
2、第三版手机内部系统文件分析
(1)Private篇
字典 101f9cfe
软件注册信息,rsc文件 10003a3f\import\apps
软件安装文件的备份,有些程序删除后在程序管理里有残余,在这删除 10202dce
Java程序存放文件夹 102033E6\MIDlets
卡上主题存放文件夹守 10207114\import
BounceMP3 Ringtoneeditor 20000c0f
QuickMark 20004FFE
JAVA程序 102033E6
MAIL2短信邮件 1000484b
CapsuleSE 20001271
ThemeDIY 20004A20
office suit sheet 20002ee2
office suit word 20002ee3
office suit docslauncher 20002ee4
smartmovie a0000b68
skyforce A0000BF4
skyforce reload A0000BF5
QReader a0000c49
MWeather A0000C98
Y-brower A00007A6
photorite a00008B1
SuperMiners A020D913
BestCalc A0000790
Sudoku AB736950
OggPlay F000A661
S-Tris2 F0202C7F
(2)SD卡的目录分析
data\mbook 掌上书院安装后配置文件存放文件夹,如果遇到书打不开可以把其中的umdrcnt.lst,mdstng删掉,再打开
Images 照片图片存放位置。照片默认是在“图像”文件夹内,用手机安装的管理软件或数据线方式(数据线方式仅可以看到E盘,即扩展卡)显示的文件夹是Images
具体显示:设置拍照存储在内存,文件路径是 C:\Date\Images\2006××**\图像◎◎◎.JPG;设置拍照存储在卡上,文件路径是 E:\Images\2006××**\图像◎◎◎.JPG。如果是按照 工具-文件管理路径查看,那么无论打开手机内存还是扩展卡,均存储在 图像文件夹下,表示方式相同 :2006××**
2006××**\图像◎◎◎.JPG,是你把照片名称设置为“文字”照片格式名称。××为月份,为先字母后数字的组合表示方法,即保证你在一个月内如果有非常多的次数的拍照,24个字母和10位数字可以保证你有240次最大拍照次数,而每次的数量可以是N次。
如果设置为日期,则上述表示的方式就改变为2006××**\2006××**◎◎◎.JPG
◎◎◎为总计数,除非你格机或者刷机,否则一直会积累下去
Installs 存放安装文件。
Music Downloads 机子自带浏览器下载音乐后,都存在这里
MyMusic 音乐模式下歌存在这里
Sounds 铃声存放文件夹
Videos 动画存放文件夹
resource\apps 程序文字资源存在这里,大多是rsc文件
resource\help 程序自带帮助文件存放在这里
resource\plugins 好像是放插件的地方,但是目前只有rsc文件
System\[102072c3] 目前不明
System\Install\Registry Java程序安装记录文件
System\Apps\Opera Opera安装后建立
System\Data\Opera 文件夹下opera.ini可调节缓存大小,cache4目录为缓存目录
(3)C盘system篇
【通讯录】→c:\system\data\contacts.Cdb同C:\system\data\cntmodel.ini
【功能表】→c:\system\data\applications.Dat
【待机状态模式】→c:\system\data\scshortcutengine.ini
【彩信设置】→c:\system\data\mms_setting.Dat
【短信设置】→c:\system\data\smsreast.Dat,smssegst.Dat,sms_settings.Dat
【闹钟设置】→c:\system\data\alarmserver.lnl
【连接设置】→c:\system\data\cdbv3.Dat
【记事本】→c:\system\data\notepad.Dat wap
【书签】→c:\system\data\bookmarks1.db
【 情景模式】→c:\system\data\profiles
【日程表】→c:\system\data\calendar
【收藏夹】→c:\system\favourites注意:【可以将这些文件移动到e:\system\favourites中】
反安装文件: c/system/install这个目录下的是 (前提:软件装在C盘),都可以删除,但是如果删除了,在程序管理列表中就没有了,只能直接删除e\system\apps\下对应目录。
安装记录文件:C/system/install下的install.log要删除安装记录文件,就将些文件删除即可。
c\system\apps下的目录里是设置和存档文件。
3、智能手机常用的指令秘籍:
*#06# :IMEI 码,也就是我们所说的手机串号,几乎所以手机都适用, IMEI 就是“国际移动装备辨识码”, IMEI =TAC+FAC+SNR+SP,其中TAC是批准型号码,共6位,FAC是最后组装地代码,共2位,但由于现在已经有JS已经能改串号了,所以NOKIA将所有的7、8位都改成00了,就是说已经看不出生产地了,SNR是序号,共6位,SP是备用码,就1位。
*#0000#(部分型号如果不起作用,可按*#型号代码#,如*#6110#) :手机版本信息,显示后一共会出现3行信息,第一行是手机软件当前版本,第二行是此版本软件发行日期,这个版本的发布时间为2004年6月28日,第三行是手机型号代码。
*#7370#:恢复出厂设置(软格机),这个命令一般是在手机处于错误或系统垃圾过多的情况下使用格机命令,格机前可以通过第三方软件或6600PC套件备份一下你的名片夹或需要的资料,格机时一定要保持电量充足,不要带充电器格机,格机时只显示“NOKIA”字样还有亮屏幕,没格完千万不要强迫关机和拔电池,以免造成严重后果,格机完成后重新输入时间,再恢复你的名片夹和资料就可以了,格机可以恢复一切原始设置,将C:盘内容全部清空,再写入新的系统信息,注意的是此格机不影响MMC卡内容。
*#7780#:恢复出厂设置,等同于功能表——工具——设置——手机设置——常规——原厂设定,注意此命令仅是恢复设置,不同于格机,恢复后名片夹、图片、文档等全部依然存在,只是设置还原了,有些朋友因设置错误而不知如何改回来就可以使用这个命令了。
*#92702689#:显示的总通话时间。此通话时间格式化,刷机后不会改变,有效防止2手机器。
以上的秘技有部分是需要输入锁码的,这里所说的锁码也就是手机密码,不过不要和SIM卡密码弄混了,手机锁码的设置是在:功能表——工具——设置——安全性设置——手机和SIM卡——锁码,其初始锁码为:12345,只要需要输入锁码的地方默认值都是12345,更改过手机锁码的以新锁码为准。
4、手机格式化
格机有二种方法:
1)、软格:在手机上输入 *#7370#之后要求你输入锁码,初始密码是:12345,如果你更改过手机密码,那就是更改后的密码(不是SIM卡密码),之后出现白屏,只显示NOKIA字样,2~3分钟后格机完成,重新输入时间。
2)、硬格:先关机,在开机的时候按住拨号键、“*”键、“3”键,打开电源手别松开,直到“NOKIA”字样出现(此过程不能松开任何一个按键)。稍稍等几秒直至出现“Formating……/”字样,这时方可松开以上按键。就开始格式化了。此格式化比较彻底,不会出现格式化无效的问题。过几分钟,系统格式化完成,手机自动重启并进入待机画面。
以上格机需要注意:保持电量绝对充足,格机途中不能企图关机,不能插充电器等。一般以软格为先。(记得格机前一定先备份好自己要的数据资料等)。
5、恢复出厂设置:
待机画面输*#7780#,等同于功能表——工具——设置——手机设置——常规——原厂设定,注意此命令仅是恢复设置,不同于格机,恢复后名片夹、图片、文档等全部依然存在,只是设置还原了,有些朋友因设置错误而不知如何改回来就可以使用这个命令了。
6、格机后成英文时如何改为中文:
打开MENU - SETTINGS - PHONE SETT - GENERAL - PERSONALISATION - LANGUAGE
- PHONE LANUAGE 简体中文
7、C盘清理技巧1)文件传送法(建议剩余8兆以下的用):首先,把信息的存储指定到机器存储,然后看自己机器内存有多大。用其他蓝牙设备给你发送一个大于8兆的文件,直到你的手机显示剩余空间不足,自动断开传送为止(手机在接受文件时机身内存不够用,系统就自动清理内存,还不够的话就自动断开连接)。C盘的内存就会变大。 2)浏览法清理理法:用随机的网络浏览器上网(占用内存大),多开些网页,直到提示内存不足无法开网页时,退出浏览,再清空缓存(此方法也只适用于机身内存比较小的3250和N71,7610等)
3)换卡法:只使用一个SIM卡,手机的运行速度会变慢,需要清理C盘垃圾文件。最简单的方法是取MINISD卡接着换SIM卡后再开机。待机3-5分钟后关机换回原来的SIM卡。这样Series60系统就会重新将C盘的数据重写一次,自动清除了原来无用的文件。
8、解决系统死机点滴:
1)、在进行程序操作的时候,按键的速度要慢些,不能过快,否则会导致死机、重启、黑屏、白屏等现象(特别是第三版手机,在进入一些菜单的过程中,会有需要 20 秒左右才能进入的情况,此时乱按键会导致系统冲突而死机)。
2)、遇到开机出现“系统错误”,停在“NOKIA”白色画面不动的情况,就按住“笔形键”,狂按“确认键”(打勾键),强制进入机子,然后用seleq删除C和E底下的system/recogs文件夹,关机->开机(此方法还适合装了新软件后不能带卡开机等故障)。
3、遇到开启程序时死机,尽可能让手机自动重启,宁可多等几分钟,也尽量不用拔电池的方法重启动(这样对手机硬件不利)。
Saturday, February 7, 2009
Get To Know Linux: Understanding smb.conf
Next to the xorg.conf file (read my Get To Know Linux: Understanding xorg.conf for more) the smb.conf file might be the most misunderstood of all files. Part of the reason for this is because the default file is, well, rather large and confusing. When you compare what you need vs what you have (in the default at least), you will be surprised at how simple Samba can be to configure.
After Samba is installed the smb.conf file will be around 533 lines long. Fear not. It’s much easier than it seems.
The smb.conf file is broken into sections. Each section will start with a line that looks like:
[TITLE]
Where TITLE is the actual title of the block. Each block represents either a configuration or a share that other machines can connect to. You will, at minimum, have a global block and a single share.
Global
The global block is one of the more important blocks in your smb.conf file. This block defines the global configuration of your Samba server. This block begins with:
[global]
Within your blocks your configuration lines will be made up of:
option = value
statements.
The most important statements you will need in your global block are:netbios name= NAME
workgroup = WORKGROUP_NAME
security = SECURITY_TYPE
encrypt passwords = YES/NO
smb passwd file = /path/to/smbpasswd
interfaces = ALLOWED_ADDRESSES
The values for each option above should be self explanatory. But there is one thing to note. If you are encrypting passwords you will need to add users (with passwords) with the smbpasswd command.
Within the global block one of the more important options is the security option. This option refers to authentication (how users will be able to log in). There are five different types of security:
- ADS - Active Directory Domain
- Domain - User verification through NT Primary or Backup Domain
- Server - Samba server passes on authentication to another server
- Share - Users do not have to enter username or password (until they try to access a specific directory)
- User - Users must provide valid username/password. This is the default.
Share Blocks
The next blocks will refer to individual shares. You will need a different block for each directory you want to share to Samba users. A typical share block will look like this:[SHARE NAME]
comment = COMMENT
path = /path/to/share
writeable = YES/NO
create mode = NUMERIC VALUE
directory mode = NUMERIC VALUE
locking = YES/NO
Everything in caps above will be defined according to your needs. The tricky entries will be the create and directory modes. What this does is define permissions for any file created as well as the share directories. So the values will be in the form of 0700 or 0600 (depending upon your permission needs). Remember, you will need a share block for every directory you want to share out.
Naturally there are plenty of options that can be used in Samba. Many of these options will fall in the global block.
Printer Block
You can also define a block to share out printers. This block will start with:
[printers]
and will contain options like:comment = COMMENT
path = /PATH/TO/PRINTER/SPOOL
browseable = YES/NO
guest ok = YES/NO
writable = YES/NO
printable = YES/NO
create mode = NUMERIC VALUE
Sample smb.conf
I have an external drive that I mount to /media/music and I share out to my home network with the following smb.conf file:[global]
netbios name = MONKEYPANTZ
workgroup = MONKEYPANTZ
security = user
encrypt passwords = yes
smb passwd file = /etc/samba/smbpasswd
interfaces = 192.168.1.1/8
[wallen music]
comment = Music Library
path = /media/music
writeable = yes
create mode = 0600
directory mode = 0700
locking = yes
And that’s it. That is my entire smb.conf file. Granted I am only sharing out a single directory, but it shows how simple smb.conf can be to configure.
Friday, February 6, 2009
Get To Know Linux: Understanding xorg.conf
For most Linux users the xorg.conf file is one of those files that makes many Linux users cringe with fear upon the threat of having to configure. There is a reason for that, it’s complex. But when you have an understanding of the pieces that make up the whole puzzle, configuring X Windows becomes much, much easier.
But now the Linux community has distributions, such as Fedora 10, that do not default to using an xorg.conf file. This is great news for many users. However, it’s bad news when, for some reason, X isn’t working or you have specific needs that the default isn’t meeting. With that in mind we’re going to break down the xorg.conf file so that you will be able to troubleshoot your X Windows configuration when something is wrong.
The Basics
The first thing you need to know is that xorg.conf (located typically in /etc/X11) is broken up into sections. Each section starts with the tag Section and ends with the tag EndSection. Each section can be broken into subsections as well. A subsections starts with the tag SubSection and ends with the tag EndSubSection. So a typical section with subsections contains the tags:
Section Name
Section Information
SubSection Name
SubSection information
EndSubSection
EndSection
Of course you can’t just use random sections. There are specific sections to use. Those sections are:
- Files - pathnames for files such as fontpath
- ServerFlags - global Xorg server options
- Module - which modules to load
- InputDevice - keyboard and pointer (mouse)
- Device - video card description/information
- Monitor - display device description
- Modes - define video modes outside of Monitor section
- Screen - binds a video adapter to a monitor
- ServerLayout - binds one or more screens with one or more input devices
- DRI - optional direct rendering infrastructure information
- Vendor - vendor specific information
Each section will have different information/options and is set up:
Option Variable
Let’s take a look at a sample section. We’ll examine a Device section from a laptop. The section looks like:
Section "Device"
Identifier "device1"
VendorName "VIA Technologies, Inc."
BoardName "VIA Chrome9-based cards"
Driver "openchrome"
Option "DPMS"
Option "SWcursor"
Option "VBERestore" "true"
EndSection
The above section configures a Via Chrome video card (often a tricky one to get running) using theopenchrome driver. Here’s how this section breaks down:
- The identifier (labled “device1″) connects this section to Screen section with the Device “device1″option.
- The VendorName and BoardName both come from the make and model of the video adapter.
- The Driver is the driver the video card will use.
- Option “DPMS” - this enables the Display Power Management System.
- Option “SWcursor” - this enables the cursor to be drawn by software (as opposed to the HWcursor drawing by hard ware).
- Option “VBERestore” “true” - allows a laptop screen to restore from suspend or hibernate.
The lengthiest section of your xorg.conf file will most likely be your Screen section. This section will contain all of the subsections that contain the modes (resolutions) for your monitor. This section will start off like this:
Section "Screen"
Identifier "screen1"
Device "device1"
Monitor "monitor1"
DefaultColorDepth 24
Notice how the above section references both a device and a monitor. These will refer to other sections in the xorg.conf file. This section also contains the DefaultColorDepth which will define the default color depth for your machine. In the case above the default is 24. Now, take a look below at the SubSections of this section:
Subsection "Display"
Depth 8
Modes "1440x900" "1280x800"
EndSubsection
Subsection "Display"
Depth 15
Modes "1440x900" "1280x800"
EndSubsection
Subsection "Display"
Depth 16
Modes "1440x900" "1280x800"
EndSubsection
Subsection "Display"
Depth 24
Modes "1440x900" "1280x800"
EndSubsection
EndSection
As you can see there is a SubSection for four different color depths. Included in those subsections is the default 24. So when X reads the DefaultColorDepth option it will automatically attempt to set the modes configured in the Depth 24 subsection. Also notice that each subsection contains two resolutions. X will attempt to set the first resolution (in the case above our first default is 1440×900) and move on to the next if it can not set the first. Most likely X will be able to set the first.
Final Thoughts
This is only meant to be an introduction to the xorg.conf configuration file. As you might guess, xorg.conf, can get fairly complex. Add to the complexity numerous options available for each section and you have a valid case to make sure you RTFM (read the fine man page.) And the man page is an outstanding resource to find information on all of the available options. To read the man page issue the command man xorg.conf from the command line.
By having a solid understanding of the xorg.conf file you won’t have any problems fixing a fubar’d X installation or tweaking your xorg.conf file to get the most from your new video card.
Thursday, December 11, 2008
Battle of the Hardware-Boosting Hacks
Jailbreak tools for iPhones/iPod touch
When the iPhone 3G and its 2.0 software was released, some of us thought that might be the end of jailbreaking, or opening up your device to third-party, non-approved applications (and, in some cases, mobile carriers). We thought wrong, as there were many apps worth jailbreaking for, and the process got much simpler with the Mac-based Pwnagetool and Winpwn for Windows. The greater issue is that Apple's been roundly criticized for rejecting any software that "replicates" its own apps, and is somewhat secretive about just why it kills and delays other apps, so jailbreaking will likely always have a home on Apple's multi-touch devices.
Canon Hacker's Development Kit
If you've ever been intrigued by time-lapse photography, motion-sensing shutters that can capture lightning, or being able to shoot videos of any serious length, you might not need to shell out for a semi-serious DSLR model—if you've got a Canon, that is. The CHDK lets you do all that and more, including record your photos in the very work-able RAW format, get way more on-screen information about your shots and their settings, and, as Adam put it, generally turn your point-and-shoot into a super-camera. The possibilities are vast, given the number of user-created scripts the CHDK can run. And, in true hacker fashion, you can even play a game or two on your LCD screen (while you pretend to be setting up that staged photo mom and dad want, perhaps).
Homemade Wi-Fi extenders
Sure, you could give Linksys (or Buffalo, or D-Link, or Apple, et al.) the extra cash for an extended, wider-range router than the standard box you've tucked away in the living room or office. But if you don't mind doing just a few minutes of DIY work, you can also create your own higher-powered antennas. We've covered a few ways of doing so, including tinfoil and paper parabolas, internal wiring replacements, and, for that steampunk feel, cooking strainer extenders. If you want to actually boost the power your router gives up, well, we're covering that farther down, but these are all relatively safe and damage-free ways to ensure a solid connection throughout your house.
XBOX Media Center (and its variants)
Ever since our boss bought a "classic," first-generation XBOX off eBay and turned it into a media center with the open-source XBOX Media Center, she's been using to organize all the media that makes it to her television, stereo, and other screens. In the meantime, XBMC has spawned a number of intriguing remixes and spin-offs, including Boxee, and now works on pretty much any platform that's got video cards and a hard drive—Windows, Mac, Linux, XBOX models, and even Apple TVs. If buying another whole system just to watch your downloaded videos and stream MP3s across the house sounds like overkill, use what you've got with XBMC.
The Hackintosh
A good number of folks are impressed with Apple's OS X operating system, yet can't bring themselves to pay the hefty premium for the hardware that Apple says is required for it. But since Steve Jobs & Co. made the switch to Intel processors, a community of hackers has been working to make Tiger/Leopard/et. al. run on gear you can assemble yourself, and, as Adam showed us, there's now a command-line-free way to install OS X on a "Hackintosh" PC. Checking out the benchmarks, you'll see there's not a lot, if any, performance loss in using unlicensed hardware, and the best part is you can have the case and your peripherals look however you want, and cost whatever you can afford.
Super-Router upgrades — DD-WRT and Tomato
As mentioned above, some home network routers just can't reach around all the walls in your house. And if you want to set up specific bandwidth rules—giving you, say, lots of room for World of Warcraft at night, but throttling your BitTorrents while you're actually working—you're usually out of luck. Unless, that is, you've loaded DD-WRT or Tomato on your router. We've walked through installations of both systems and toured a bit of what they can do. Plus, as many have attested, they can make a router more stable, freeing you from frequent oh-crap-hope-that-page-saves runs to re-plug your misbehaved little guy.
Homebrew Wii
It's hard to say, exactly, why Nintendo didn't include DVD playback capabilities on its Wii game system, given that its games are, well, DVDs. So it was only a matter of time before a few clever folks came up with a way of getting homebrew apps and DVD playback on the Wii, without anyone having to bust out a screwdriver or soldering iron. You can add a lot more to that Homebrew Wii channel, and, if you're cool with Nintendo absolutely disliking your doing so, play backed-up Wii games on it. While you're feeling geeky, you can put your Wiimotes to use in reverse by controlling your computer with them.
Rescue old hardware with Linux
Okay, so it's not really doing anything to your hardware that a Windows installation doesn't do. But saving an older, lower-powered computer from e-cycling (or a long, slow twilight in the garage) is one of the main reasons Lifehacker readers switched to, or tried out, Linux. Seriously dated gear can often work just fine in a modern world with Puppy Linux or Damn Small Linux, and your mid-range systems—like, say, the last Dell you bought before this one—can be spun into a slick, webapp-focused system with gOS.
Rockbox and iPod Linux
Update: Added after the initial post, due to popular demand/outcry. No intentional slight intended!
In case you needed an example of Linux completely transforming seemingly outdated hardware into the new hotness, music monster Rockbox, and its games-focused counterpart iPod Linux. Rockbox is the glitzier of the pair, adding customized themes, CoverFlow-like shuffling and other current-generation features to your seemingly out-paced iPod, but iPod Linux gives you some serious freedom inside your tiny computer, and has a pretty nice roster of games. For a look around Rockbox, check out Adam's tour of the latest release.
Friday, September 19, 2008
Display interface IP addresses
To display IP addresses assigned to router’s interfaces (excluding interfaces with no IP address) use show ip interface brief | exclude unassigned command.
Here is a sample printout:
C1#show ip int brief | excl unassigned
Interface IP-Address OK? Method Status Protocol
FastEthernet0/0 172.16.0.1 YES NVRAM up up
Serial1/0 10.0.7.17 YES NVRAM up up
Loopback0 10.0.1.1 YES NVRAM up up
Tunnel0 192.168.0.1 YES manual up up
You could define an alias to create a new IOS command generating this printout, for example, alias exec ipconfig show ip interface brief | exclude unassigned.
Define new IOS commands with the alias functionality
For example, if want to have the ipconfig command that displays interface IP configuration, you can configure
#alias exec ipconfig show ip interface
When you execute ipconfig ifname the alias is expanded into show ip interface ifname and displays the IP configuration of a single interface.
Monday, September 8, 2008
101个Google技巧
- 更加全面地用Google搜索的最好方式是点击高级搜索。
- 它可以让你搜索更加精准的词组,“所有词组”或者是适当的搜索框里输入词组的某一个特定关键词。
- 在高级搜索里你依然可以自定义在一张页面上展示多少个搜索结果,你所寻找的信息语言和文件格式。
- “搜索以下网站或网域”可以让你通过输入一个顶级域名(如.co.uk)来限定搜索结果。
- 你也可以点击“日期、使用权限、数字范围和更多”的链接以获取更高级的功能。(Google中文直接分条在页面展示。)
- 保存设置,这些高级功能大多也可以在Google首页的搜索框中通过命令行参数来实现
- Google的主要搜索可以无形地用布尔结构“AND”来结合。你当输入smoke fire - 它表示寻找smoke AND fire.
- 要让Google搜索Smoke 或者fire,只需要输入smoke OR fire.
- 你也可以用 | 来代替OR。如:smoke | fire.
- 像AND 和 OR 这样的布尔结构对大小写非常敏感。他们必须是全部大写。
- 搜索专有名词,然后输入用括号括住的一个或者几个关键词。比如water (smoke OR fire)
- 寻找短语,可以把它们放在引号里。比如:"there’s no smoke without fire"。
- 同义搜索来寻找那些类似的信息,只须在你的关键词臆加一根波浪线,比如:~eggplant.
- 用减号来排除关键词,如:new pram -ebay 可以让搜索结果排除来自Ebay的婴儿车信息。
- 像 I, and, then ,if 这类普通词语是要被Google 忽略的。他们被称作停滞词语。
- 而加号却可以让这些停滞词语给包含进来,比如:fish +and chips.
- 如果一个停滞词语被包含在那些作为短语的引用标记中间的句子中时,这些词语是被Google允许的。
- 你也可以要求Google进行简省搜索,试一下:Christopher Columbus discovered *
- 用数字范围功能来搜索数字范围。例如:搜索价位在300英到500英磅之间的索尼电视可以用以下字串:Sony TV £300..£500。
- 通过高级搜索Google认可13种主要文件格式,其中包括Office, Lotus, PostScript, Shockwave Flash 和text。
- 搜索这些文件只需直接使用修饰符 filetype:[文件扩展名]。例如:soccer filetype:pdf.
- 要排除整个文件格式,只需使用以前我们排除关键词时使用的相同布尔句法:橄榄球 -filetype:doc
- 事实上,只要你的语法正确,你可以混合使用任何布尔搜索运算符。举个例子便是:"sausage and mash" -onions filetype:doc
- Google也有很多功能强大却隐藏着的搜索参数,例如“intitle” 仅仅只会搜索网页标题(titles).你可以用这个例子试一试:intitle:网页设计
- 如果你只是寻找文件而不是网页,只需用index of 代替intitle:参数。它可以帮助你寻找网络和FTP目录。
- inurl这个修饰语只会搜索网页的网址,不妨用这个例子试一试 inurl:spices
- 通过 inurl:vien/view.shtml 你可以找到在线的网络摄像头。
- inanchor这个修饰语非常特别,它仅仅只会寻找那些作为超链接的文本。
- 想知道有多少链接指向一个网站。可以试试这个语法:link:网址 - 比如link:www.mozilla.org
- 同样的,你也可以通过 related:修饰语来找到Google认为相似的内容。比如: related:www.microsoft.com
- info:site_name 这个修饰语可以返回关于某特定页面的信息。
- 同样的,在普通搜索后点击"相似网页"可以链接到Google认为相似的页面结果。
- 如果只想搜索某一个风址里的内容,可能用site: 来实现,比如说search tips site:www.techradar.com.
- 上述技巧通过像www.dmoz.org这样的目录网站并动态地生成网址。
- 也可直接进入Google Directory这样的人工挑选出来的数量有限的数据库网站,网址是www.direcory.google.com。
- intitle和inurl这样的布尔运算符像OR一样在Google Directory中同样适用。
- 当你用Google图片搜索时,用site:的修饰语可以只搜索某一个网站内的图片,比如 dvd recorder site:www.amazon.co.uk。
- 同样的,用"site:.com"只会返回带有.com域名后缀网站里的结果。
- Google新闻(news.google.com)有他自己的布尔运算符。例如“intext” 只会从一条新闻的主体内容里查询结果。
- 在Google新闻里如果你用“source:”这个运算符,你可以得到特定的新闻存档。比如:heather mills source:daily_mail
- 通过"location:"过滤器你可以等到特定国家的新闻,比如 location:uk
- 同样的Google博客搜索(blogsearch.google.com)也有它自己的句法。你可以搜索某篇日志的标题,比如 "inblogtitle:
" - Google的普通搜索也可以确实也可以得到精确的结果,不如用"movie:
" 来寻找电影评论。 - “film:”修饰语效果也一样。
- 在搜索框里输入上映时间,Google会提示你提交你的邮编,然后Google就会告诉你什么时候什么地方将会有好戏上演。
- 如果想要一个专门的电影搜索页面,可以去www.google.co.uk/movies
- 如果你圈选了“记住地点”后,下次你查询电影放映时间只需要输入电影名字就够了。
- Google确实在电影方面的搜索上下了些功夫。比如在搜索框中输入“director:<电影名>”你将得到什么结果?你肯定猜到了吧。
- 如果想得到演员名单,如需输入“cast:name_of_film”
- 在乐队名、歌曲名或者专辑名前加上“music:”可以得到相关的音乐信息和评论。
- 如果你在搜索框里输入“weather London”便可以得到伦敦最近四天完整的天气预报。
- Google也内置了词典,在搜索框里用"define:the_word"试试。
- Goolge保存了网站过去的内容。你可以直接搜索某个页面在Google服务器里的缓存,相关句法是“keyword cache:site_url”
- 相应的,直接在搜索框里输入“cache:site_url”可以直接进入缓存页面。
- 如果你手边没有计算器,只要记住Google同样内置了这么一个功能。输入“12*15”然后点击搜索试试。
- Google的内置计算器不但可以转换尺寸还可以理解自然语言。搜索一下“14 stones in kilos”
- 汇率转换也同样适用,试试“200 pounds in euros”
- 如果你知道某货币的代码,将得到更加可靠的结果,例如"200 GBR in EUR"
- 温度呢?Google也没有放过,输入“98 f to c”便可以把华氏转换为摄氏。
- 想知道Google到底有多聪明呢?输入“2476 in roman numerals”然后点击“搜索”就知道了。
- 你也可以保存你的Google使用习惯偏好,只需要在www.google.com/account上注册一个帐号便可。
- 一旦有了Google帐号,不旦可以免费获得一个Gmail帐号,最主要的是可以畅通无阻地遨游于Google的世界。
- 登陆你的Google帐户,通过“iGoogle”你还可以个性化你的Google主页。
- 在“iGoogle”上点击”Add a Tab”来添加多个内容模块,Google会根据你添加的甩有模块来自适应整个页面。
- “iGoogle”允许你为主页更换模板,点击”Select Theme”便可改变现有的默认主题。
- 有一些”iGoogle”主题会随着时间的改变而改变,比如”Sweet Dreams”就是一个随着白天到夜晚的更迭而改变的一款主题。
- 点击”Try something new” 下面的”More” 就可以看到一个更加完整的Google网站列表和一些新的功能。
- “Custom Search”帮助你为你自己的网站建立一个Google牌的搜索引擎。
- 另外,那张列表还忘掉了一个很有用的服务“Personalised Search”,不过你可以通过访问www.google.com/psearch来使用它。(一个保存你搜索记录的服务——译者注)
- 这个页面列出了你最近的搜索,并按特定分类来区分他们,点击”pause” 就可以阻止Google记录你的搜索历史。
- 点击”Trends”可以看到你最访问的网站,你最搜索最多的条目以及最常点击的链接。
- 个性化搜索同样包括了一个书签服务,它帮助你在线保存书签并可以在任何地方获取他们。
- 更方便的是,你可以在”iGoogle”上添加一个书签模块来添加或访问它们。
- 你知道你还可以搜索Google返回的结果么?滑到搜索结果页面底部便可以找到那链接。
- 在你的查询后面附加你的邮编便可以搜索本地信息。
- 找地图?只需要在搜索关键词后面多写一个”map”,比如“Leeds map”
- Google搜索图片(这里指直接在Google首页而不是Google Map页面,译者注)非常简单,只要你在关键词后而多写个“image”,你就会在搜索结果的顶部看到相关的图片结果。
- 神奇的是Google图片搜索可以识别人脸,在浏览器地址栏搜索结果页面网址后面添加“&imgtype=face” 确定后Google会过滤掉所有不是人的图片。
- 想关注股市行情?只需要在”stock:”后面填上公司的股票代码便可以得到从Google财经返回的结果。
- 在Google的搜索框中输入航空公司或者航班号可以获得相关的航班信息。
- 现在几点了?在地点前面加上“time”可以得到任务地方的时间。
- 你也许已经注意到了在输入关键词时Google会交替提示你的拼写,那内置的拼写检查在起作用。
- 你可以在关键词前加上”spell:”来直接调用Google的拼写检查功能。
- 点击”I’m Feeling Lucky” (手气不错)可以直接访问关键词搜索第一个结果的网页。
- 输入基于统计的查询关键词,比如population of Britain,在结果顶部Google会告诉你它的答案。
- 如果你看到的搜索有非英文结果,点击”Translate this Page” 可以看到由Google帮你翻译的英文内容。
- 你也可以搜索国外网站的内容,点击语言工具,然后选择你想要Google帮你翻译查询的国家。
- 语言工具的另一个特色是可以帮你翻译一些可自由剪贴的文本字块。
- 这里也有一个区域,你可以直接输入网址,并让Google翻译成你想要的语言。
- 在“语言工具”链接上面你可以看到一个“使用偏好”的链接,这是一个包含了一些私密设置的页面。
- 你可以明确地告诉Google你希望返回结果的语言,可根据你的喜好进行多选。
- Google的安全搜索可以保护你免受色情内容的侵犯。你可以选择性的让过滤系统更加严格或者把它完全地关闭。
- 在使用偏好里,你可以改变Google搜索单页显示结果的结果数,默认为10.
- 你也可以设置为在新窗口打开Google的搜索结果。
- 想知道他人在搜索的内容或者提高你自己网站的Pagerank值(Google自行开发的网页质量等级排名评估算法,Pagerank值越高的网页在搜索结果里越靠前,译者注)?去www.google.com/zeitgeist看看。
- 另一个强大的实验性功能可以在www.google.com/trends找到,你可以知道哪些是热门搜索条目。
- 在Google趋势搜索框里输入以逗号间隔的多个关键词,可以对比他们的搜索表现。
- 想用克林贡语搜索?去www.google.com/intl/xx-klingon就可以了。
- 也许你提线木偶里的瑞典厨师是你的榜样?点击www.google.com/intl/xx-bork看看。
- 在搜索框里输入“answer to life, the universe and everything”,你肯定会被结果吓一跳。
- Google还可以告诉你独角兽有多少只角,(够搞笑吧)。输入“number of horns on a unicorn”看看。
Monday, August 20, 2007
run-parts scripts: a note about naming
run-parts is used (on Debian systems, anyway) to run the scripts in /etc/cron.daily (hourly, weekly, etc) on the appropriate schedule. I had trouble this week with a Perl script I’d dropped into /etc/cron.daily failing to run. Ran fine from the command line, of course. Odd.
Eventually it occurred to me, after a little light man page reading, to try run-parts --test /etc/cron.daily (which just prints the names of the scripts that would run). Script failed to show up. Most Odd.
I finally found the answer via Google, although a slightly less
light reading of the man page would have helped. Scripts to be run by
run-parts must adhere to a particular naming convention - in
particular, no .xx endings. So my script.pl script wasn’t being picked up due to that .pl ending. I renamed it to script and all was well.
(I’m not actually sure what the logic of this is; I’m assuming it’s likely to be historical reasons. You can alter it with the --lsbsysinit option, if you prefer that. I know the .xx ending is by no means essential, but I prefer in general to have a quick visual of what language I’ve written a script in.)
Powered by ScribeFire.
October 24th, 2008 at 12:20 am
Something I often need to do is match lines against a regexp, and print out a matching group within that line. But I have never been able to find a way to do this in awk, and end up resorting to Perl.
So - is there a way to do something like this?
/abc([0-9]+)def/ { print group(1); }
so that input of:
abc654def
produces:
654
Thanks!
October 24th, 2008 at 8:57 am
Unix User:
That is easily done with gawk, see the last tip. You could do eg
gawk -v RS='abc([0-9]+)def' 'RT{gsub(/[^0-9]/,"",RT)print RT}Of course, the exact regexes used for RS and in the gsub vary from time to time depending on what you want to achieve. Another solution is using gensub(), again from gawk.
Unfortunately, standard awk regexes lack backreferences, so getting what you want using standard awk would not be easy.
October 24th, 2008 at 11:39 am
To pkrumins: something got lost during reformatting. The first two examples that uses GNU awk and RT should be as follows:
“…like for example when we want everything that matches something. With GNU awk, we can do this:
October 24th, 2008 at 11:40 am
ok, now I see
Let’s see it this time it works:
“…like for example when we want everything that matchessomething . With GNU awk, we can do this:
gawk -v RS=’?tag>’ ‘RT==””‘
or again
gawk -v RS=’?tag>’ ‘!(NR%2)’
October 24th, 2008 at 3:29 pm
pkrumins:
no, using int(n)==n to check if a number is valid in an IPv4 address won’t work. It will accept, for example, “+100″ which is not valid in a dotted quad IPv4 address.
October 24th, 2008 at 11:43 pm
@Unix User:
tr should be the tool of your choice:
October 25th, 2008 at 1:34 am
[…] 10 Awk Tips, Tricks and Pitfalls - good coders code, great reuse This article takes a look at ten tips, tricks and pitfalls in Awk programming language. They are mostly taken from the discussions in #awk IRC channel. (tags: awk linux shell reference bash) […]
October 25th, 2008 at 2:22 am
Alternate solution for the IP address validation function:
function ok(n){ return (n !~ /[^0-9]/) && (n>=0 && nThis just adds an additional test to assert that the value being tested contains only numeric characters.
October 25th, 2008 at 2:25 am
(I’ll try that again) Alternate solution for the IP address validation function - same as your first suggestion, but with a condition allowing only numeric values:
function ok(n){ return (n !~ /[^0-9]/) && (n>=0 && nOctober 25th, 2008 at 6:12 am
[…] Smashing Magazine 40 devastatingly simple ways the web can save you big money | News | TechRadar UK 10 Awk Tips, Tricks and Pitfalls - good coders code, great reuse 60 Useful Adobe AIR Applications You Should Know | Tools How to create a stunning and smooth popup […]
October 25th, 2008 at 7:37 am
[…] 10 Awk Tips, Tricks and Pitfalls - good coders code, great reuse (tags: reference tips programming awk scripting bash) […]
October 25th, 2008 at 12:22 pm
[…] On sait qu’il y a des fans ici, donc un petit tour par la pour lire 10 petites astuces awk. […]
October 25th, 2008 at 2:01 pm
Keep us updated with what goes there at Mt. View, CA
Good luck newbie googler (Y)
October 25th, 2008 at 7:58 pm
Found this site due to the article you wrote on perl one-liner youtube downloader (which no longer works) and I see you’ve digressed. Why would anyone go from perl to awk? Did you hit your head?
October 26th, 2008 at 1:35 am
[…] On sait qu’il y a des fans ici, donc un petit tour par la pour lire 10 petites astuces awk. […]
October 27th, 2008 at 6:27 pm
@zts:
That’s a good one! Thank you.
@PS:
I agree perl is more powerful of awk. But I think you’ll agree that that is not a valid reason to stop using awk (or sed, or cat, or all the other tools that perl could easily replace).
October 29th, 2008 at 3:13 am
Hi!
This is a really helpful article thanks!
I am trying to remove all double quotes and angled brackets, and replcase all semicolons and colons with newlines in a text file with gawk.
Can you help?
I have trouble making my scripts work.
I use gawk3.1.6 for Windows and following are some of the codes I have tried.
awk {gsub(/,/,"\n")}1awk {gsub(/"/,"")}1October 29th, 2008 at 2:28 pm
@Steve Kinoshita:
To remove all double quotes and angled brackets, try this:
To replace all semicolons and colons with newlines, try this:
Since you say you’re using windows, I suggest you put your awk program in a separate file, and then run it using
November 3rd, 2008 at 1:22 am
In “Pitfall: validate an IPv4 address” awk returns not-zero when the input is a valid IPv4 address and zero otherwise. That’s because awk’s boolean arithmetic assigns 1 to True and 0 to False.
This is not what a shell programmer would expect because shells usually act in the opposite way: true=0 and false=1.
Thus, the final “shell-compatible” script should be:
awk -F '[.]' 'function ok(n) {
return (n ~ /^([01]?[0-9]?[0-9]|2[0-4][0-9]|25[0-5])$/)
}
{exit (! ( ok($1) && ok($2) && ok($3) && ok($4) ) )}'
However, I’d prefer to use something simpler:
function ok(n) {
if (n ~ /[^[:digit:]]/)
return 1==0;
return (n
Not fully tested but should work the same
my 2 pennies