如何在awk中将分隔string拆分为数组?

如何在包含pipe道符号的情况下拆分string 在里面。 我想分裂他们在arrays中。

我试过了

 echo "12:23:11" | awk '{split($0,a,":"); print a[3] a[2] a[1]}' 

哪个工作正常。 如果我的string像"12|23|11"那么我如何将它们拆分成一个数组?

你有没有尝试过:

 echo "12|23|11" | awk '{split($0,a,"|"); print a[3],a[2],a[1]}' 

要在awk中将string拆分为数组,我们使用函数split()

  awk '{split($0, a, ":")}' # ^^ ^ ^^^ # | | | # string | delimiter # | # array to store the pieces 

如果没有分隔符,则使用默认为空格的FS

 $ awk '{split($0, a); print a[2]}' <<< "a:bc:de" c:d 

我们可以给一个分隔符,例如::

 $ awk '{split($0, a, ":"); print a[2]}' <<< "a:bc:de" bc 

这相当于通过FS设置它:

 $ awk -F: '{split($0, a); print a[1]}' <<< "a:bc:de" bc 

在gawk你也可以提供分隔符作为正则expression式:

 $ awk '{split($0, a, ":*"); print a[2]}' <<< "a:::bc::de" #note multiple : bc 

甚至可以通过使用第四个参数来查看每一步的分隔符:

 $ awk '{split($0, a, ":*", sep); print a[2]; print sep[1]}' <<< "a:::bc::de" bc ::: 

我们引用手册页:

split(string,array [,fieldsep [,seps]])

将string分成由fieldsep分隔的片段,并将片段存储在数组中,并将分隔符string存储在seps数组中。 第一部分存储在数组1中 ,第二部分存储在数组[2]中,等等。 第三个参数fieldsep的string值是一个描述拆分string的正则expression式(很像FS可以是一个描述拆分inputlogging的地方的正则expression式)。 如果省略fieldsep,则使用FS的值。 split()返回创build的元素的数量。 seps是一个gawk扩展,其中seps [i]是数组[i]和数组[i + 1]之间的分隔符string。 如果fieldsep是单个空格,则任何前导空格将进入seps [0],并且任何尾随空格将进入seps [n],其中n是split()的返回值(即数组中元素的数目)。

请更具体! 你是什​​么意思“它不工作”? 发布确切的输出(或错误消息),您的操作系统和awk版本:

 % awk -F\| '{ for (i = 0; ++i <= NF;) print i, $i }' <<<'12|23|11' 1 12 2 23 3 11 

或者,使用分割:

 % 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 "12|23|11" | awk '{split($0,a,"|"); print a[3] a[2] a[1]}' 

我不喜欢echo "..." | awk ... echo "..." | awk ...解决scheme,因为它会调用不必要的forkexec系统调用。

我更喜欢Dimitre的解决scheme

 awk -F\| '{print $3 $2 $1}' <<<'12|23|11' 

或者稍微缩短版本:

 awk -F\| '$0=$3 $2 $1' <<<'12|23|11' 

在这种情况下,输出logging放在一起,这是一个真实的条件,所以它被打印。

在这种特定情况下,可以通过设置awk内部variables来保留stdinredirect:

 awk -v T='12|23|11' 'BEGIN{split(T,a,"|");print a[3] a[2] a[1]}' 

我用了很久的ksh ,但在bash中可以通过内部string操作来pipe理。 在第一种情况下,原始string被内部终结符分割。 在第二种情况下,假设string始终包含由一个字符分隔符分隔的数字对。

 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 

玩笑? 🙂

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]}' 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]}' 

应该pipe用。