9.2. Manipulating Strings

9.2. Manipulating Strings

1、String Length

expr "$string" : '.*'

3、Index这个表达式跟java的用法好像不同

expr index $string $substring

    Numerical position in $string of first character in $substring that matches.


   5 echo `expr index "$stringZ" 1c`              # 3

   6 # 'c' (in #3 position) matches before '1'.

4?{string:position:length}负数参数的用法有点怪

    Extracts $length characters of substring from $string at $position.


  16 echo ${stringZ:-4}                           # abcABC123ABCabc

  17 # Defaults to full string, as in ${parameter:-default}.

  18 # However . . .

  19

  20 echo ${stringZ:(-4)}                         # Cabc

  21 echo ${stringZ: -4}                          # Cabc

  22 # Now, it works.

  23 # Parentheses or added space "escape" the position parameter.

  24

  25 # Thank you, Dan Jacobson, for pointing this out.

而且下面这段不懂:


    If the $string parameter is "*" or "@", then this extracts a maximum of

$length positional parameters, starting at $position.

       1 echo ${*:2}          # Echoes second and following positional

parameters.

       2 echo ${@:2}          # Same as above.

       3

       4 echo ${*:2:3}        # Echoes three positional parameters, starting

at second.

5、Example 9-12. Emulating getopt其中的字符串处理不甚明了


  14       if [ ${1:0:1} = '/' ]

  15       then

  16           tmp=${1:1}               # Strip off leading '/' . . .

  17           parameter=${tmp%%=*}     # Extract name.

  18           value=${tmp##*=}         # Extract value.

  19           echo "Parameter: '$parameter', value: '$value'"

  20           eval $parameter=$value

  21       fi

6、awk处理函数不懂


  14 # The awk equivalent of ${string:pos:length} is

substr(string,pos,length).

  15 echo | awk '

  16 { print substr("'"${String}"'",3,4)      # skid

  17 }

  18 '

7、9.2.2. Further Discussion进一步讨论的几个例子没看

英语疑问:

1、emulation, getopt

A simple emulation of getopt  using substring extraction constructs.

9.1. Internal Variables

9.1. Internal Variables

1、不懂:


$DIRSTACK

    the top value in the directory stack (affected by pushd and popd)

    This builtin variable corresponds to the dirs command, however dirs shows

    the entire contents of the directory stack.

2、

 


$EUID

    "effective" user ID number

    Identification number of whatever identity the current user has assumed,

    perhaps by means of su.

    Caution The $EUID is not necessarily the same as the $UID.

3、


  $GLOBIGNORE

    A list of filename patterns to be excluded from matching in globbing.

4、


     root# echo ${GROUPS[1]}

     1

5、


    $IFS defaults to whitespace (space, tab, and newline), but may be changed,

    for example, to parse a comma-separated data file. Note that $* uses the

    first character held in $IFS. See Example 5-1.

     bash$ echo $IFS | cat -vte

     $

     bash$ bash -c 'set w x y z; IFS=":-;"; echo "$*"'

     w:x:y:z

6、IFS是空格时,字符间的多个空格视为一个分隔符,第一个字符前面的空格会忽略不计。见例子ifs.sh。


              14 IFS=" "

              15 var=" a  b c   "

 ...

              26 IFS=:

              27 var=":a::b:c:::"               # Same as above, but substitute

运行结果:


[mdx@localhost abs-exercises]$ ./ex9-1.sh

IFS=" "

-------

the arg is: [a]

the arg is: [b]

the arg is: [c]

IFS=:

-----

the arg is: []

the arg is: [a]

the arg is: []

the arg is: [b]

the arg is: [c]

the arg is: []

the arg is: []

[mdx@localhost abs-exercises]$

7、$LINENO 不懂


$LINENO

    This variable is the line number of the shell script in which this

variable

    appears. It has significance only within the script in which it appears,

    and is chiefly useful for debugging purposes.

       1 # *** BEGIN DEBUG BLOCK ***

       2 last_cmd_arg=$_  # Save it.

       3

       4 echo "At line number $LINENO, variable \"v1\" = $v1"

       5 echo "Last command argument processed = $last_cmd_arg"

       6 # *** END DEBUG BLOCK ***

8、$PIPESTATUS不懂,并且在本机上的执行结果与书中的不同


     bash$ echo $PIPESTATUS

     0

     bash$ ls -al | bogus_command

     bash: bogus_command: command not found

     bash$ echo $PIPESTATUS

     141

     bash$ ls -al | bogus_command

     bash: bogus_command: command not found

     bash$ echo $?

     127

...

          bash$ echo ${PIPESTATUS[@]}

9、不懂

$PWD的:


      22 # rm -f .[^.]* ..?*   to remove filenames beginning with multiple

dots.      23 # (shopt -s dotglob; rm -f *)   will also work.

      24 # Thanks, S.C. for pointing this out.

10、不懂$SHELLOPTS的用法


[mdx@localhost abs-exercises]$ echo $SHELLOPTS

braceexpand:emacs:hashall:histexpand:history:interactive-comments:monitor

11、$SHLVL的用法


$SHLVL

    Shell level, how deeply Bash is nested. If, at the command line, $SHLVL is

    1, then in a script it will increment to 2.

12、$TMOUT的用法不懂,例子example9-2~9-4不懂

13、$UID,下面这段话的意思不懂

This is the current user's real id, even if she has temporarily assumed

    another identity through su.

14、example9-7太复杂了,留在这里备忘


    Caution The $* and $@ parameters sometimes display inconsistent and

            puzzling behavior, depending on the setting of $IFS.

    ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━

    Example 9-7. Inconsistent $* and $@ behavior

15、set命令的用法


[mdx@localhost abs-exercises]$ set a b c

[mdx@localhost abs-exercises]$ echo $1 $2 $3

a b c

[mdx@localhost abs-exercises]$

16、$!的用法

书上的例子:

LOG=$0.log

COMMAND1="sleep 100"

echo "Logging PIDs background commands for script: $0" >> "$LOG"

# So they can be monitored, and killed as necessary.

echo >> "$LOG"

# Logging commands.

echo -n "PID of \"$COMMAND1\":  " >> "$LOG"

${COMMAND1} &

echo $! >> "$LOG"

# PID of "sleep 100":  1506

# Thank you, Jacques Lederer, for suggesting this.

#下面这句不大懂:eval, kill -9

#possibly_hanging_job & { sleep ${TIMEOUT}; eval 'kill -9 $!' &> /dev/null; }      

# Forces completion of an ill-behaved program.

# Useful, for example, in init scripts.

# Thank you, Sylvain Fourmanoit, for this creative use of the "!" varia

英语疑问:

1、subtleties, nuances

This requires learning their subtleties and nuances.

2、necessarily

$SHELL does not necessarily give the correct answer.

3、collation order, mishandled

$LC_COLLATE

    Often set in the .bashrc or /etc/profile files, this variable controls

    collation order in filename expansion and pattern matching. If mishandled,

    LC_COLLATE can cause unexpected results in filename globbing.

4、revert, customary

To revert to the customary behavior of bracket matching, set LC_COLLATE to C by an export LC_COLLATE=C in /etc/profile and/or ~/.bashrc.

5、expedient

In a script, it may be expedient to temporarily add a directory to the path

    in this way.

6、likewise

         $SHELL, the name of the user's login shell, may be set from /

         etc/passwd or in an "init" script, and it is likewise not a

         Bash builtin.

8.2. Numerical Constants

8.2. Numerical Constants

1、Example 8-4. Representation of numerical constants

同C语言一样,字符也是整数。但是@和_代表是多少不知道?而且把它们转化为十进制的方法忘记了。

  32 let "b64 = 64#@_"

  33 echo "base-64 number = $b64"             # 4031

  34 # This notation only works for a limited range (2 - 64) of ASCII characters  35 # 10 digits + 26 lowercase characters + 26 uppercase characters + @ + _

  36

  37

  38 echo

  39

  40 echo $((36#zz)) $((2#10101010)) $((16#AF16)) $((53#1aA))

  41                                          # 1295 170 44822 3375

英语疑难: evaluates

A number with an embedded # evaluates as BASE#NUMBER (with range and notational restrictions).

8.1. Operators

Chapter 8. Operations and Related Topics

8.1. Operators

1、Example 8-1. Greatest common divisor最大公约数的算法不懂,里面的练习:判断命令行参数是否是整数不懂,记在这里。

2、发现一个问题,bash的算术操作符只能进行整数的运算,要进行其它的复杂点的运算:如开方、小数等怎么办呢?

3、Example 8-2. Using Arithmetic Operations

这个例子有不少地方不明白,记在这里以后进一步解决:

我知道 let "z = 2 + 3" 相当于 (( z = 2 + 3 )),根据:


Similar to the let command, the ((...)) construct permits arithmetic expansion

and evaluation.

1)、


      10 : $((n = $n + 1))

      11 #  ":" necessary because otherwise Bash attempts

      12 #+ to interpret "$((n = $n + 1))" as a command.

2)、      20 n=$(($n + 1))

3)、

      23 : $[ n = $n + 1 ]

      24 #  ":" necessary because otherwise Bash attempts

      25 #+ to interpret "$[ n = $n + 1 ]" as a command.

      26 #  Works even if "n" was initialized as a string.

4)、

      29 n=$[ $n + 1 ]

      30 #  Works even if "n" was initialized as a string.

      31 #* Avoid this type of construct, since it is obsolete and

nonportable.

      32 #  Thanks, Stephane Chazelas.

5)、      44 : $(( n++ ))       # : $(( ++n )) also works.

6)、      47 : $[ n++ ]         # : $[ ++n ]] also works

4、bash不能处理浮点数:


Bash does not understand floating point arithmetic. It treats numbers containing a decimal point as strings.

5、

if [ $condition1 -a $condition2 ] 相当于 if [[ $condition1 && $condition2 ]]

,但是&&不能用在[...]结构中,这些有什么规律吗?真不好掌握啊。

6、Example 8-3. Compound Condition Tests Using && and ||


6 if [ "$a" -eq 24 ] && [ "$b" -eq 47 ]

17 #  Note:  if [[ $a -eq 24 && $b -eq 24 ]]  works.

20 #    (The "&&" has a different meaning in line 17 than in line 6.)

我不懂&&在6行和17行有什么区别?

7、不懂 $((...))的用法


     bash$ echo $(( 1 && 2 )) $((3 && 0)) $((4 || 0)) $((0 || 0))

     1 0 1 0

英语疑问:

1、Modulo turns up surprisingly often in various numerical recipes.

2、erroneous

An operation that takes a variable outside these limits will give an erroneous result.

3、flip, relevant, fly

"Bit flipping" is more relevant to compiled languages, such

as C and C++, which run fast enough to permit its use on the fly.

4、miscellaneous operators

5、evaluated

All the operations are evaluated (with possible side effects), but only the last operation is returned.

7.4. Nested if/then Condition Tests 7.5. Testing Your Knowledge of Tests

7.4. Nested if/then Condition Tests

嵌套条件测试相当于复合条件测试中的 &&

7.5. Testing Your Knowledge of Tests


  10      if [ -f /usr/bin/netscape -a -f /usr/share/doc/HTML/index.html ]; then  11              netscape /usr/share/doc/HTML/index.html &

  12      fi

有2个问题:

1、在测试条件中多个测试条件(如上:-f -a -f)的组合规则和形式是怎么样的?

2、"netscape /usr/share/doc/HTML/index.html &"后面加一个&是什么意思?

另外,这章布置了习题,分析/etc/X11/xinit/xinitrc文件中的条件语句,这遍就略过习题了。下同。

英语疑问:

1、excerpt

This file contains quite a number of if/then tests, as the following excerpt shows.

2、failsafe, fallbacks

 # failsafe settings.  Although we should never get here

 # (we provide fallbacks in Xclients as well) it can't hurt.

7.3. Other Comparison Operators

1、太复杂了,记不住的,有没有什么规则呀?

The == comparison operator behaves differently within a double-brackets         test than within single brackets.


            1 [[ $a == z* ]]    # True if $a starts with an "z" (pattern matchin            2 [[ $a == "z*" ]]  # True if $a is equal to z* (literal matching).

            3

            4 [ $a == z* ]      # File globbing and word splitting take place.

            5 [ "$a" == "z*" ]  # True if $a is equal to z* (literal matching).

            6

            7 # Thanks, St?phane Chazelas

2、测试数值用[ "$a" -ne "$b" ],测试字符串用[ "$a" != "$b" ]。

3、Example 7-6. Testing whether a string is null通过几个例子反复说:测试字符串一定要用双引号把字符串变量括起来!从前面看,测试数值变量同样是把变量用双引号括起来的,这样,可以总结说,无论是数值变量和字符串变量都必须加双引号。

4、Example 7-7. zmore中测试文件类型的语句,不懂


if [ ${filename##*.} != "gz" ]

# Using bracket in variable substitution.

then

  echo "File $1 is not a gzipped file!"

  exit $NOTGZIP

fi

5、复合比较:

1)、[[ condition1 && condition2 ]]相当于 [ "$exp1" -a "$exp2" ]

2)、在比较空字符串时,应该在有可能是空字符串的字符串前加上额外的字符,文中说:


As S.C. points out, in a compound test, even quoting the string variable

     might not suffice. [ -n "$string" -o "$a" = "$b" ] may cause an error with

     some versions of Bash if $string is empty. The safe way is to append an

     extra character to possibly empty variables, [ "x$string" != x -o "x$a" =

     "x$b" ] (the "x's" cancel out).

英语疑问:

1、globbing

File globbing and word splitting take place.

2、Caution advised, however.

  10 #  Bash permits integer operations and comparisons on variables

  11 #+ whose value consists of all-integer characters.

  12 #  Caution advised, however.

3、sealing wax, cabbages and kings

   2 #  str-test.sh: Testing null strings and unquoted strings,

   3 #+ but not strings and sealing wax, not to mention cabbages and kings . . .

4、compound comparison

5、suffice:

As S.C. points out, in a compound test, even quoting the string variable

     might not suffice.

6、the "x's" cancel out(上面5的2))

7.2. File test operators

1、example 7-4

不懂下面的代码,这不是纯bash的代码,那是什么代码?


#This, however, is a better method:

#

#find "somedir" -type l -print0|\

#xargs -r0 file|\

#grep "broken symbolic"|

#sed -e 's/^\|: *broken symbolic.*$/"/g'

#

#but that wouldn't be pure bash, now would it.

2、一句有技巧的语句:


[ $# -eq 0 ] && directorys=`pwd` || directorys=$@

结构:

如果 (参数个数=0)返回值为真,就会继续执行:directorys=当前目录;执行成功它的exit状态为0,也是真,那么就会停止执行||(或);

如果 (参数个数=0)返回值为假,就不会执行 &&(与)了,但会执行||(或)。

3、example 7-4

[ -h "$element" -a ! -e "$element" ] ,预先知道这句的作用是找到破坏了的符号连接,但是这句的作用怎么来的不懂;

另外,[ - ]与邻近的字符之间必须有空格。

英语疑问:

1、sticky:

Commonly known as the "sticky bit," the save-text-mode flag is a special

    type of file permission.

2、absent:

"not" -- reverses the sense of the tests above (returns true if condition

    absent).

3、would:

but that wouldn't be pure bash, now would it.

7.1. Test Constructs

1、command &>filename redirects both the stdout and the stderr of command to

    filename.


       1 if cmp a b &> /dev/null  # Suppress output.

       2 then echo "Files a and b are identical."

       3 else echo "Files a and b differ."

       4 fi

2、|

    pipe. Passes the output of previous command to the input of the next one,

    or to the shell. This is a method of chaining commands together.


      12 word=Linux

      13 letter_sequence=inu

      14 if echo "$word" | grep -q "$letter_sequence"

      15 # The "-q" option to grep suppresses output.

      16 then

      17   echo "$letter_sequence found in $word"

      18 else

      19   echo "$letter_sequence not found in $word"

      20 fi

3、这个嵌套结构有点怪,还有(())和[[]]的有什么区别?

  它的结构是:

  if ()

    if()

    then()

    else()

    endif

  then()

  endif

  总觉得不如这样:

  if ()

  then

    if()

    then()

    else()

    endif

    ()

  endif

 · An if/then construct can contain nested comparisons and tests.


       1 if echo "Next *if* is part of the comparison for the first *if*."

       2

       3   if [[ $comparison = "integer" ]]

       4     then (( a < b ))

       5   else

       6     [[ $a < $b ]]

       7   fi

       8

       9 then

      10   echo '$a is less than $b'

      11 fi

4、example 7-1

bash里面的测试命令真是多呀?test [] [[]] (()) let ... ,快昏了。

[0]和[1]和[-1]的测试结果都是true,不懂?

[ -n "$xyz" ] 里面的-n什么作用?(

[]就是test命令

在man test中查到如下:

[-n] STRING

              the length of STRING is nonzero

)


#!/bin/bash

#  Tip:

#  If you're unsure of how a certain condition would evaluate,

#+ test it in an if-test.

echo

echo "Testing \"0\""

if [ 0 ]      # zero

then

  echo "0 is true."

else

  echo "0 is false."

fi            # 0 is true.

echo

echo "Testing \"1\""

if [ 1 ]      # one

then

  echo "1 is true."

else

  echo "1 is false."

fi            # 1 is true.

echo

echo "Testing \"-1\""

if [ -1 ]     # minus one

then

  echo "-1 is true."

else

  echo "-1 is false."

fi            # -1 is true.

echo

echo "Testing \"NULL\""

if [ ]        # NULL (empty condition)

then

  echo "NULL is true."

else

  echo "NULL is false."

fi            # NULL is false.

echo

echo "Testing \"xyz\""

if [ xyz ]    # string

then

  echo "Random string is true."

else

  echo "Random string is false."

fi            # Random string is true.

echo

echo "Testing \"\$xyz\""

if [ $xyz ]   # Tests if $xyz is null, but...

              # it's only an uninitialized variable.

then

  echo "Uninitialized variable is true."

else

  echo "Uninitialized variable is false."

fi            # Uninitialized variable is false.

echo

echo "Testing \"-n \$xyz\""

if [ -n "$xyz" ]            # More pedantically correct.

then

  echo "Uninitialized variable is true."

else

  echo "Uninitialized variable is false."

fi            # Uninitialized variable is false.

echo

xyz=          # Initialized, but set to null value.

echo "Testing \"-n \$xyz\""

if [ -n "$xyz" ]

then

  echo "Null variable is true."

else

  echo "Null variable is false."

fi            # Null variable is false.

echo

# When is "false" true?

echo "Testing \"false\""

if [ "false" ]              #  It seems that "false" is just a string.

then

  echo "\"false\" is true." #+ and it tests true.

else

  echo "\"false\" is false."

fi            # "false" is true.

echo

echo "Testing \"\$false\""  # Again, uninitialized variable.

if [ "$false" ]

then

  echo "\"\$false\" is true."

else

  echo "\"\$false\" is false."

fi            # "$false" is false.

              # Now, we get the expected result.

#  What would happen if we tested the uninitialized variable "$true"?

echo

exit 0

5、[[]]比[]更加有用?


The [[ ]] construct is the more versatile Bash version of [ ]. This is the

extended test command, adopted from ksh88.

...

Tip Using the [[ ... ]] test construct, rather than [ ... ] can prevent many

    logic errors in scripts. For example, the &&, ||, <, and > operators work

    within a [[ ]] test, despite giving an error within a [ ] construct.

6、

Following an if, neither the test command nor the test brackets ( [ ] or

     [[ ]] ) are strictly necessary.

例如:


[mdx@localhost abs-exercises]$ if dir; then echo "dir success"; else echo

"fail" ; fi

3    ch4-2.txt  ch7-0-1.sh  ctrl-m.sh  ex2-2.sh  ex4-5.sh  ex5-2.sh  ex7-1.sh

3]]  ch5-2.txt  ch7-1.txt   env.txt    ex2-3.sh  ex4-6.sh  ex6-1.sh  plan2.txt

b]]  ch6.txt    ctrl-h.sh   ex2-1.sh   ex4-2.sh  ex4-7.sh  ex7-0.sh  plan.txt

dir success

[mdx@localhost abs-exercises]$

[mdx@localhost abs-exercises]$ if Dir; then echo "dir success"; else echo

"fail" ; fi

bash: Dir: command not found

fail

[mdx@localhost abs-exercises]$

7、(( 1 / 0 )) 2>/dev/null不懂?


  29 (( 1 / 0 )) 2>/dev/null                          # Illegal division by 0.

  30 #           ^^^^^^^^^^^

  31 echo "Exit status of \"(( 1 / 0 ))\" is $?."     # 1

  32

  33 # What effect does the "2>/dev/null" have?

  34 # What would happen if it were removed?

  35 # Try removing it, then rerunning the script.

8、英语疑问:

1)The (( ... )) and let ... constructs also return an exit status of 0 if the

    arithmetic expressions they evaluate expand to a non-zero value.

2)This is in marked contrast to using the test and [ ] constructs previously discussed.

5.2. Escaping

1、Example 5-2(怎么样才能显示下面这个 $escape ?)

 


      54 escape=$'\033'                    # 033 is octal for escape.

      55 echo "\"escape\" echoes as $escape"

      56 #                                   no visible output.

 

2、echo -e的用法:


[mdx@localhost abs-exercises]$ echo "\n"

\n

[mdx@localhost abs-exercises]$ echo -e "\n"

[mdx@localhost abs-exercises]$

[mdx@localhost abs-exercises]$ echo "\\"

\

[mdx@localhost abs-exercises]$ echo -e "\\"

\

[mdx@localhost abs-exercises]$ echo -e '\\'

\

[mdx@localhost abs-exercises]$ echo  '\\'

\\

3、可是说是一些非常烦人的用法,不用去记它,平常也用不着吧。

Note The behavior of \ depends on whether it is itself escaped, quoted, or

     appearing within command substitution or a here document.


        1                       #  Simple escaping and quoting

        2 echo \z               #  z

        3 echo \\z              # \z

        4 echo '\z'             # \z

        5 echo '\\z'            # \\z

        6 echo "\z"             # \z

        7 echo "\\z"            # \z

        8

        9                       #  Command substitution

       10 echo `echo \z`        #  z

       11 echo `echo \\z`       #  z

       12 echo `echo \\\z`      # \z

       13 echo `echo \\\\z`     # \z

       14 echo `echo \\\\\\z`   # \z

       15 echo `echo \\\\\\\z`  # \\z

       16 echo `echo "\z"`      # \z

       17 echo `echo "\\z"`     # \z

       18

       19                       # Here document

       20 cat <<EOF

       21 \z

       22 EOF                   # \z

       23

       24 cat <<EOF

       25 \\z

       26 EOF                   # \z

       27

       28 # These examples supplied by St?phane Chazelas.

4、\可以起到续行符的作用,文中的叙述:

The escape also provides a means of writing a multi-line command. Normally,

each separate line constitutes a different command, but an escape at the end of

a line escapes the newline character, and the command sequence continues on to

the next line.

例如:下面的dir这个命令被分成3行来写,每行一个字符:)


[mdx@localhost abs-exercises]$ d\

> i\

> r

ch4-2.txt  ctrl-h.sh  ex2-1.sh  ex2-3.sh  ex4-5.sh  ex4-7.sh  plan2.txt

ch5-2.txt  ctrl-m.sh  ex2-2.sh  ex4-2.sh  ex4-6.sh  ex5-2.sh  plan.txt

[mdx@localhost abs-exercises]$ dir

ch4-2.txt  ctrl-h.sh  ex2-1.sh  ex2-3.sh  ex4-5.sh  ex4-7.sh  plan2.txt

ch5-2.txt  ctrl-m.sh  ex2-2.sh  ex4-2.sh  ex4-6.sh  ex5-2.sh  plan.txt