How do I split up a line and rearrange its element

2019-07-10 11:51发布

I have some data on a single line like below

abc edf xyz rfg yeg udh

I want to present the data as below

abc
xyz
yeg


edf
rfg
udh

so that alternate fields are printed with newline separated. Are there any one liners for this?

12条回答
虎瘦雄心在
2楼-- · 2019-07-10 12:50

Another Perl solution:

use strict;
use warnings;

while (<>)
{
    my @a = split;
    my @b = map { $a[2 * ($_%(@a/2)) + int($_ / (@a /2))]  . "\n" } (0 .. @a-1); 
    print join("\n", @a[0..((@b/2)-1)], '', @a[(@b/2)..@b-1], '');
}

You could even condense it into a real one-liner:

perl -nwle'my @a = split;my @b = map { $a[2 * ($_%(@a/2)) + int($_ / (@a /2))]  . "\n" } (0 .. @a-1);print join("\n", @a[0..((@b/2)-1)], "", @a[(@b/2)..@b-1], "");'
查看更多
乱世女痞
3楼-- · 2019-07-10 12:52
$ echo 'abc edf xyz rfg yeg udh' |awk -vRS=" " 'NR%2;NR%2==0{_[++d]=$0}END{for(i=1;i<=d;i++)print _[i]}'
abc
xyz
yeg
edf
rfg
udh

For newlines, i leave it to you to do yourself.

查看更多
做自己的国王
4楼-- · 2019-07-10 12:53

My attempt in haskell:

Prelude> (\(x,y) -> putStr $ unlines $ map snd (x ++ [(True, "")] ++ y)) $ List.partition fst $ zip (cycle [True, False]) (words "abc edf xyz rfg yeg udh")
abc
xyz
yeg

edf
rfg
udh
Prelude>
查看更多
再贱就再见
5楼-- · 2019-07-10 12:53

Here is yet another way, using Bash, to manually rearrange words in a line - with previous conversion to an array:

echo 'abc edf xyz rfg yeg udh' | while read tline; do twrds=($(echo $tline)); echo -e "${twrd[0]} \n${twrd[2]} \n${twrd[4]} \n\n ${twrd[1]} \n${twrd[3]} \n${twrd[5]} \n" ; done 

Cheers!

查看更多
再贱就再见
6楼-- · 2019-07-10 12:56

The following awk script can do it:

> echo 'abc edf xyz rfg yeg udh' | awk '{
    for (i = 1;i<=NF;i+=2){print $i}
    print "";
    for (i = 2;i<=NF;i+=2){print $i}
    }'
abc
xyz
yeg

edf
rfg
udh
查看更多
Melony?
7楼-- · 2019-07-10 12:56

Here's the too-literal, non-scalable, ultra-short awk version:

awk '{printf "%s\n%s\n%s\n\n%s\n%s\n%s\n",$1,$3,$5,$2,$4,$6}'

Slightly longer (two more characters), using nested loops (prints an extra newline at the end):

awk '{for(i=1;i<=2;i++){for(j=i;j<=NF;j+=2)print $j;print ""}}'

Doesn't print an extra newline:

awk '{for(i=1;i<=2;i++){for(j=i;j<=NF;j+=2)print $j;if(i==1)print ""}}'

For comparison, paxdiablo's version with all unnecessary characters removed (1, 9 or 11 more characters):

awk '{for(i=1;i<=NF;i+=2)print $i;print "";for(i=2;i<=NF;i+=2)print $i}'

Here's an all-Bash version:

d=(abc edf xyz rfg yeg udh)
i="0 2 4 1 3 5"
for w in $i
do
    echo ${d[$w]}
    [[ $w == 4 ]]&&echo
done
查看更多
登录 后发表回答