当字符串中包含管道符号|时如何分割字符串。 我想把它们拆分到数组中
|
我试着
echo "12:23:11" | awk '{split($0,a,":"); print a[3] a[2] a[1]}'
这很好。如果我的字符串像"12|23|11",那么我如何把它们分割成一个数组?
"12|23|11"
笑话?:)
echo "12|23|11" | awk '{split($0,a,"|"); print a[3] a[2] a[1]}'呢
echo "12|23|11" | awk '{split($0,a,"|"); print a[3] a[2] a[1]}'
这是我的输出:
p2> echo "12|23|11" | awk '{split($0,a,"|"); print a[3] a[2] a[1]}' 112312
所以我想它还是有用的。
应该工作。
你有没有试过:
echo "12|23|11" | awk '{split($0,a,"|"); print a[3],a[2],a[1]}'
% awk -F\| '{ for (i = 0; ++i <= NF;) print i, $i }' <<<'12|23|11' 1 12 2 23 3 11
或者,使用split:
% awk '{ n = split($0, t, "|") for (i = 0; ++i <= n;) print i, t[i] }' <<<'12|23|11' 1 12 2 23 3 11
编辑:在Solaris上,你需要使用POSIX awk (/usr/xpg4/bin/awk)才能正确处理4000个字段。
我不喜欢echo "..." | awk ...解决方案,因为它调用不必要的fork和__abc2系统调用。
echo "..." | awk ...
fork
我更喜欢迪米特里的解决方案
awk -F\| '{print $3 $2 $1}' <<<'12|23|11'
或者更短一点的版本:
awk -F\| '$0=$3 $2 $1' <<<'12|23|11'
在这种情况下,输出记录放在一起是一个真条件,所以它被打印出来。
在这种特定情况下,可以通过设置awk内部变量来避免stdin重定向:
stdin
awk -v T='12|23|11' 'BEGIN{split(T,a,"|");print a[3] a[2] a[1]}'
我使用了ksh很长一段时间,但在bash中,这可以通过内部字符串操作来管理。在第一种情况下,原始字符串被内部终止符分割。在第二种情况下,假设字符串总是包含由一个字符分隔符分隔的数字对。
T='12|23|11';echo -n ${T##*|};T=${T%|*};echo ${T#*|}${T%|*} T='12|23|11';echo ${T:6}${T:3:2}${T:0:2}
所有情况下的结果都是
112312
要将字符串分割为awk中的数组,我们使用函数split():
awk
split()
awk '{split($0, array, ":")}' # \/ \___/ \_/ # | | | # string | delimiter # | # array to store the pieces
如果没有指定分隔符,则使用FS,默认为空格:
FS
$ awk '{split($0, array); print array[2]}' <<< "a:b c:d e" c:d
我们可以给出一个分隔符,例如::
:
$ awk '{split($0, array, ":"); print array[2]}' <<< "a:b c:d e" b c
这相当于通过FS来设置它:
$ awk -F: '{split($0, array); print array[1]}' <<< "a:b c:d e" b c
在GNU Awk中,你也可以提供分隔符作为regexp:
$ awk '{split($0, array, ":*"); print array[2]}' <<< "a:::b c::d e #note multiple : b c
甚至可以通过使用第四个参数来查看每一步的分隔符:
$ awk '{split($0, array, ":*", sep); print array[2]; print sep[1]}' <<< "a:::b c::d e" b c :::
让我们引用GNU awk的手册页:
Split (string, array [, fieldsep [, seps]]) 将array[2]0分割成以array[2]1分隔的块,并将这些块存储在array[2]2中,将分隔符字符串存储在array[2]3数组中。第一部分存储在array[1]中,第二部分存储在array[2]中,依此类推。第三个参数array[2]1的字符串值是一个描述在哪里分割array[2]0的regexp(就像array[2]6可以是一个描述在哪里分割输入记录的regexp)。如果省略array[2]1,则使用array[2]6的值。split()返回创建的元素数量。array[2]3是一个gawk扩展,其中seps[i]是array[i]和array[i+1]之间的分隔符字符串。如果array[2]1是单个空格,则任何前导空格都将进入seps[0],任何尾随空格都将进入seps[n],其中split()1是split()的返回值(即数组中元素的数量)。
Split (string, array [, fieldsep [, seps]])
将array[2]0分割成以array[2]1分隔的块,并将这些块存储在array[2]2中,将分隔符字符串存储在array[2]3数组中。第一部分存储在array[1]中,第二部分存储在array[2]中,依此类推。第三个参数array[2]1的字符串值是一个描述在哪里分割array[2]0的regexp(就像array[2]6可以是一个描述在哪里分割输入记录的regexp)。如果省略array[2]1,则使用array[2]6的值。split()返回创建的元素数量。array[2]3是一个gawk扩展,其中seps[i]是array[i]和array[i+1]之间的分隔符字符串。如果array[2]1是单个空格,则任何前导空格都将进入seps[0],任何尾随空格都将进入seps[n],其中split()1是split()的返回值(即数组中元素的数量)。
array[2]
array[1]
gawk
seps[i]
array[i]
array[i+1]
seps[0]
seps[n]
实际上awk有一个叫做“输入字段分隔符变量”的特性。这是如何使用它。它不是一个真正的数组,但它使用内部的$变量。对于分割一个简单的字符串,它更容易。
echo "12|23|11" | awk 'BEGIN {FS="|";} { print $1, $2, $3 }'
我知道这是个老问题,但我想也许有人喜欢我的把戏。特别是因为这个解决方案不局限于特定数量的项目。
# Convert to an array _ITEMS=($(echo "12|23|11" | tr '|' '\n')) # Output array items for _ITEM in "${_ITEMS[@]}"; do echo "Item: ${_ITEM}" done
输出将是:
Item: 12 Item: 23 Item: 11
挑战:解析并存储带有空格的分割字符串,并将它们插入到变量中。
解决方案:最好和最简单的选择是将将字符串列表转换为数组,然后解析它转换为带索引的变量。下面是一个转换和访问数组的示例。
例子:解析每一行的磁盘空间统计:
sudo df -k | awk 'NR>1' | while read -r line; do #convert into array: array=($line) #variables: filesystem="${array[0]}" size="${array[1]}" capacity="${array[4]}" mountpoint="${array[5]}" echo "filesystem:$filesystem|size:$size|capacity:$capacity|mountpoint:$mountpoint" done #output: filesystem:/dev/dsk/c0t0d0s1|size:4000|usage:40%|mountpoint:/ filesystem:/dev/dsk/c0t0d0s2|size:5000|usage:50%|mountpoint:/usr filesystem:/proc|size:0|usage:0%|mountpoint:/proc filesystem:mnttab|size:0|usage:0%|mountpoint:/etc/mnttab filesystem:fd|size:1000|usage:10%|mountpoint:/dev/fd filesystem:swap|size:9000|usage:9%|mountpoint:/var/run filesystem:swap|size:1500|usage:15%|mountpoint:/tmp filesystem:/dev/dsk/c0t0d0s3|size:8000|usage:80%|mountpoint:/export
awk -F'['|'] -v '{print $1"\t"$2"\t"$3}' file <<<'12|23|11'
代码
awk -F"|" '{split($0,a); print a[1],a[2],a[3]}' <<< '12|23|11'
输出
12 23 11