動機

想把bash的某個字串轉成大寫,但因為bash太舊,所以不能用substitution來做,只能用awk

所以來整理一下,在bash做字串處理的方式

bash substitution

  • 大寫
    • 第一個字: ${var^}
    • 所有字: ${var^^<pat>}
  • 小寫
    • 第一個字: ${var,}
    • 所有字: ${var,,<pat>}
  • 找符合的所有變數名: ${!VAR*} <= VAR1=1; VAR2=2;
  • substring: ${VAR:pos(included):len}
  • replace
    • once: ${VAR/pat1/pat2}
    • all: ${VAR//pat1/pat2}
  • remove
    • front
      • lazy: ${VAR#PAT}
      • eagal: ${VAR##PAT}
    • back
      • lazy: ${VAR%PAT}
      • eagal: ${VAR%%PAT}
  • strlen: {% raw %}${#VAR}{% endraw %}
  • default val
    • set: ${VAR:=val} <= echo $VAR # val
    • get: ${VAR:-val} <= echo $VAR # <empty>

cut

string -> [string]

像是someletters_12345_moreleters.ext只取12345 可以用cut去切,用_去分[someletters, 12345, moreleters.ext] 之後拿第2欄,cut -d '_' -f 2

awk

C的語法,py2的感覺,只有hash沒有array

awk是針對文字檔案的工具,基本上

BEGIN {}
PAT1 {}
PAT2 {}
# ....
END {}

讀第一行時會先跑BEGIN,可以初始化變數,等最後一行跑完就會跑END 之後就是一行一行看,如果對到pattern就跑那個block

注意,awk的string只有double quote,沒有single quote

function string_functions(localvar, arr) {

    localvar = "fooooobar";
    sub("fo+", "Meet me at the ", localvar); # localvar => "Meet me at the bar"
    gsub("e+", ".", localvar); # localvar => "m..t m. at th. bar"

    # Search for a string that matches a regular expression
    # index() does the same thing, but doesn't allow a regular expression
    match(localvar, "t"); # => 4, since the 't' is the fourth character

    sprintf("%s %d %d %d", "Testing", 1, 2, 3); # => "Testing 1 2 3"
    substr("foobar", 2, 3); # => "oob"
    substr("foobar", 4); # => "bar"
    length("foo"); # => 3
    tolower("FOO"); # => "foo"
    toupper("foo"); # => "FOO"
}

# /^fo+bar$/
# a > 0 (boolean exp)
$0 ~ /^fo+bar$/ {
  # Inside here, we have access to a number of useful variables, already
  # pre-loaded for us:
  # $0 is the entire line
  # $3 is the third field, the age, which is what we're interested in here
  # NF is the number of fields, which should be 3
  # NR is the number of records (lines) seen so far
  # FILENAME is the name of the file being processed
  # FS is the field separator being used, which is " " here
  # $NF => $3

  multidim[0,0] = "foo";
  assoc["foo"] = "bar";
  n = split("foo:bar:baz", arr, ":"); /* arr = ["foo", "bar", "baz"] */
  if ("foo" in assoc)
        print "Fooey!";

  for (key in assoc)
      print assoc[key];
  
  delete arr[1];

  string_functions(assoc, multidim);
}

someletters_12345_moreleters.ext只取12345當例子 awk 'BEGIN{FS="_"} {print $2}'

Ref

How To Use Bash Parameter Substitution Like A Pro awk in x minutes