Chinaunix
标题:
请问如何用 awk 提取 shell 数组下标(无序数组)
[打印本页]
作者:
raps
时间:
2015-05-26 13:52
标题:
请问如何用 awk 提取 shell 数组下标(无序数组)
本帖最后由 raps 于 2015-05-26 13:52 编辑
请问如何通过 awk 获取一个字符串中 所有 特定格式 中的部分字符。
比如从字符串
=([0]="a b" [4]="e [ f" [5]=" " [9]=" []= ")
复制代码
中获取 0 4 5 9
应用场景:
使用
set | grep -E "^BASH_VERSINFO=\("
复制代码
就可以得到 BASH_VERSINFO 数组的结构,
如:
BASH_VERSINFO=([0]="4" [1]="1" [2]="2" [3]="1" [4]="release" [5]="x86_64-redhat-linux-gnu")
复制代码
不考虑下标不为数字的情况。
有可能存在数组下标不连续的情况,这就导致从 0 循环到 “数组长度” 变得不准确。
考虑仅用正则匹配 [数字]=“ 情况,怎么获得所有的“数字”?
如得到这样的结果:
0 1 2 3 4 5
复制代码
以下可以获得所有的数字:
set | grep -E "^BASH_VERSINFO=" | awk 'BEGIN{RS="\\(\\[| \\[|\\]="}!(NR%2)'
复制代码
但是一旦数组的内用中含有 “[” 或其他敏感字符,会导此字符后面起都会获取失败。
作者:
ly5066113
时间:
2015-05-26 14:04
回复
1#
raps
目测:
set | grep "^BASH_VERSINFO=" | grep -Po '(?<=\[)\d+(?=\])'
复制代码
作者:
raps
时间:
2015-05-26 14:09
回复
2#
ly5066113
能简单说一下语法吗?不能用 awk 实现吗?
作者:
zxy877298415
时间:
2015-05-26 14:22
awk -F '[][]' '{for(i=2;i<=NF;i+=2){ print $i}}'
复制代码
回复
3#
raps
作者:
raps
时间:
2015-05-26 14:26
回复
4#
zxy877298415
多谢参与,但是这个没办法排除干扰。
作者:
ly5066113
时间:
2015-05-26 14:31
回复
3#
raps
set | awk -F '[][]' '/^BASH_VERSINFO=/{for(i=2;i<NF;i+=2)if($i~/^[0-9]+$/)print $i}'
复制代码
作者:
reyleon
时间:
2015-05-26 14:59
set | grep -E "^BASH_VERSINFO=" | awk 'BEGIN{RS="\133[0-9]+\135"}gsub(/[][]/,"",RT){print RT}'
复制代码
作者:
raps
时间:
2015-05-26 15:12
回复
7#
reyleon
请问
\133
复制代码
是什么编码的字符?可以在哪里查到?
作者:
reyleon
时间:
2015-05-26 15:13
[root@localhost ~]# man ascii
ASCII(7) Linux Programmer’s Manual ASCII(7)
NAME
ascii - the ASCII character set encoded in octal, decimal, and hexadecimal
DESCRIPTION
ASCII is the American Standard Code for Information Interchange. It is a 7-bit code. Many 8-bit codes (such as ISO 8859-1, the Linux
default character set) contain ASCII as their lower half. The international counterpart of ASCII is known as ISO 646.
The following table contains the 128 ASCII characters.
C program ’\X’ escapes are noted.
Oct Dec Hex Char Oct Dec Hex Char
------------------------------------------------------------------------
000 0 00 NUL ’\0’ 100 64 40 @
001 1 01 SOH (start of heading) 101 65 41 A
002 2 02 STX (start of text) 102 66 42 B
003 3 03 ETX (end of text) 103 67 43 C
004 4 04 EOT (end of transmission) 104 68 44 D
005 5 05 ENQ (enquiry) 105 69 45 E
006 6 06 ACK (acknowledge) 106 70 46 F
007 7 07 BEL ’\a’ (bell) 107 71 47 G
010 8 08 BS ’\b’ (backspace) 110 72 48 H
011 9 09 HT ’\t’ (horizontal tab) 111 73 49 I
012 10 0A LF ’\n’ (new line) 112 74 4A J
013 11 0B VT ’\v’ (vertical tab) 113 75 4B K
014 12 0C FF ’\f’ (form feed) 114 76 4C L
015 13 0D CR ’\r’ (carriage ret) 115 77 4D M
016 14 0E SO (shift out) 116 78 4E N
017 15 0F SI (shift in) 117 79 4F O
020 16 10 DLE (data link escape) 120 80 50 P
021 17 11 DC1 (device control 1) 121 81 51 Q
022 18 12 DC2 (device control 2) 122 82 52 R
023 19 13 DC3 (device control 3) 123 83 53 S
024 20 14 DC4 (device control 4) 124 84 54 T
025 21 15 NAK (negative ack.) 125 85 55 U
026 22 16 SYN (synchronous idle) 126 86 56 V
027 23 17 ETB (end of trans. blk) 127 87 57 W
030 24 18 CAN (cancel) 130 88 58 X
031 25 19 EM (end of medium) 131 89 59 Y
032 26 1A SUB (substitute) 132 90 5A Z
033 27 1B ESC (escape) 133 91 5B [
034 28 1C FS (file separator) 134 92 5C \ ’\\’
035 29 1D GS (group separator) 135 93 5D ]
036 30 1E RS (record separator) 136 94 5E ^
037 31 1F US (unit separator) 137 95 5F _
040 32 20 SPACE 140 96 60 `
041 33 21 ! 141 97 61 a
042 34 22 " 142 98 62 b
043 35 23 # 143 99 63 c
044 36 24 $ 144 100 64 d
045 37 25 % 145 101 65 e
046 38 26 & 146 102 66 f
047 39 27 ’ 147 103 67 g
050 40 28 ( 150 104 68 h
051 41 29 ) 151 105 69 i
052 42 2A * 152 106 6A j
053 43 2B + 153 107 6B k
054 44 2C , 154 108 6C l
055 45 2D - 155 109 6D m
056 46 2E . 156 110 6E n
057 47 2F / 157 111 6F o
060 48 30 0 160 112 70 p
061 49 31 1 161 113 71 q
062 50 32 2 162 114 72 r
063 51 33 3 163 115 73 s
064 52 34 4 164 116 74 t
065 53 35 5 165 117 75 u
066 54 36 6 166 118 76 v
067 55 37 7 167 119 77 w
070 56 38 8 170 120 78 x
071 57 39 9 171 121 79 y
072 58 3A : 172 122 7A z
073 59 3B ; 173 123 7B {
074 60 3C < 174 124 7C |
075 61 3D = 175 125 7D }
076 62 3E > 176 126 7E ~
077 63 3F ? 177 127 7F DEL
复制代码
作者:
raps
时间:
2015-05-26 15:34
回复
6#
ly5066113
如果arr 数组为
arr=([0]="[" [1]="]" [2]="[]=" [3]="[2]=")
复制代码
set | awk -F '[][]' '/^arr=/{for(i=2;i<NF;i+=2)if($i~/^[0-9]+$/)print $i}'
复制代码
将有可能落下 1
set | awk -F '[][]' '/^arr=/{for(i=0;i++<NF;)if($i~/^[0-9]+$/)print $i}'
复制代码
可以保证没有落下
作者:
raps
时间:
2015-05-26 15:38
回复
7#
reyleon
如果数组是
arr=([0]="[" [1]="]" [2]="[]=" [3]="[2]=")
复制代码
结果会多出个空格……不过应该不影响二次使用
作者:
raps
时间:
2015-05-26 15:42
回复
9#
reyleon
多谢提供。原来可以如此引用 ASCII 编码,目测一些类似回车换行的字符也可以通过这种方式使用。
作者:
raps
时间:
2015-05-26 15:48
回复
4#
zxy877298415
请问
awk -F '[][]'
复制代码
这个是以什么作为分割符的?
作者:
jason680
时间:
2015-05-26 16:11
回复
10#
raps
would you like it ?
$ set | awk '/
arr=
/{s=$0;while(1){s=substr(s,RSTART+RLENGTH);if(match(s,/\[([0-9]+)\]/,a))printf a[1]" ";else{print"";next}}}'
0 1 2 3 2
作者:
raps
时间:
2015-05-26 16:58
回复
14#
jason680
不明觉厉,完全不懂。思路不错
作者:
reyleon
时间:
2015-05-27 15:42
回复
11#
raps
那个还不完善, 还要多加两条转义才算完美.
echo 'arr=([0]="[" [1]="]" [2]="[]=" [3]="[2]=")' | awk 'BEGIN{RS="\\\133[0-9]+\\\135"}gsub(/[][]/,"",RT){print RT}'
复制代码
也可以用 gawk 4.0+ 的 FPAT 变量:
echo 'arr=([0]="[" [1]="]" [2]="[]=" [3]="[2]=")' | awk 'BEGIN{FPAT="\\\133[0-9]+\\\135"}{for(i=1;i<=NF;i++){gsub(/[^0-9]/,"",$i);print $i}}'
复制代码
作者:
reb00t
时间:
2015-05-27 16:56
>>> d = 'BASH_VERSINFO=([0]="4" [1]="2" [2]="37" [3]="1" [4]="release" [5]="i486-pc-linux-gnu")'
>>> d
'BASH_VERSINFO=([0]="4" [1]="2" [2]="37" [3]="1" [4]="release" [5]="i486-pc-linux-gnu")'
>>>
dd = re.findall('\[(\d+)\]', d, flags=0)
>>> dd
['0', '1', '2', '3', '4', '5']
复制代码
作者:
Shell_HAT
时间:
2015-05-28 09:42
回复
13#
raps
awk -F '[
]
[
]'
以蓝色的右方括号和红色的左方括号为分隔符
作者:
reyleon
时间:
2015-05-29 10:14
无聊中~~~
# echo 'arr=([0]="[" [1]="]" [2]="[0]=" [3]="[2]=")' | awk 'BEGIN{FPAT="\\\133[0-9]+\\\135"}{gsub(/\"[^\"]*\"/,"");for(i=1;i<=NF;i++){gsub(/[^0-9]/,"",$i);print $i}}'
0
1
2
3
复制代码
欢迎光临 Chinaunix (http://bbs.chinaunix.net/)
Powered by Discuz! X3.2