Как разделить линию и переставить ее элементы? - PullRequest
2 голосов
/ 23 октября 2009

У меня есть некоторые данные в одной строке, как показано ниже

abc edf xyz rfg yeg udh

Я хочу представить данные, как показано ниже

abc
xyz
yeg


edf
rfg
udh

так, чтобы альтернативные поля печатались с разделителями новой строки. Есть ли какие-нибудь вкладыши для этого?

Ответы [ 12 ]

6 голосов
/ 23 октября 2009

Следующий скрипт awk может сделать это:

> 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
4 голосов
/ 23 октября 2009

Python в том же духе, что и вышеупомянутый awk (4 строки):

$ echo 'abc edf xyz rfg yeg udh' | python -c 'f=raw_input().split()
> for x in f[::2]: print x
> print
> for x in f[1::2]: print x'

Python 1-liner (без трубы, которая идентична):

$ python -c 'f=raw_input().split(); print "\n".join(f[::2] + [""] + f[1::2])'
3 голосов
/ 25 октября 2009

Позор, что предыдущие ответы на Perl такие длинные. Вот два однострочника Perl:

echo 'abc edf xyz rfg yeg udh'|
  perl -naE '++$i%2 and say for @F; ++$j%2 and say for "",@F'

В старых версиях perl (без «say») вы можете использовать это:

echo 'abc edf xyz rfg yeg udh'|
  perl -nae 'push @{$a[++$i%2]},"$_\n" for "",@F; print map{@$_}@a;'
3 голосов
/ 23 октября 2009

Другая версия Perl 5:

#!/usr/bin/env perl
use Modern::Perl;
use List::MoreUtils qw(part);

my $line = 'abc edf xyz rfg yeg udh';

my @fields = split /\s+/, $line; # split on whitespace

# Divide into odd and even-indexed elements
my $i = 0;
my ($first, $second) = part { $i++ % 2 }  @fields;

# print them out
say for @$first;
say '';          # Newline
say for @$second;
2 голосов
/ 23 октября 2009

Просто для сравнения, вот несколько сценариев Perl для этого (в конце концов, TMTOWTDI). Довольно функциональный стиль:

#!/usr/bin/perl -p

use strict;
use warnings;

my @a = split;
my @i = map { $_ * 2 } 0 .. $#a / 2;
print join("\n", @a[@i]), "\n\n",
      join("\n", @a[map { $_ + 1 } @i]), "\n";

Мы также можем сделать это ближе к сценарию AWK:

#!/usr/bin/perl -p

use strict;
use warnings;

my @a = split;
my @i = map { $_ * 2 } 0 .. $#a / 2;
print "$a[$_]\n" for @i;
print "\n";
print "$a[$_+1]\n" for @i;

У меня не осталось способов сделать это, поэтому, если какой-нибудь другой умный Перлерс придумает другой метод, не стесняйтесь добавлять его.

1 голос
/ 26 октября 2009

Моя попытка в 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>
1 голос
/ 23 октября 2009

Вот слишком буквальная, не масштабируемая, ультракороткая awk версия:

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

Немного длиннее (еще два символа), используя вложенные циклы (печатает дополнительный символ новой строки в конце):

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

Не печатать лишний перевод строки:

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

Для сравнения, версия paxdiablo со всеми ненужными символами удалена (еще 1, 9 или 11 символов):

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

Вот версия для всех Bash:

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
1 голос
/ 23 октября 2009

Другое решение Perl:

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], '');
}

Вы могли бы даже сжать его до настоящей строки:

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], "");'
0 голосов
/ 03 сентября 2010

Вот еще один способ, используя Bash, вручную переставить слова в строке - с предыдущим преобразованием в массив:

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 

Ура! * * 1004

0 голосов
/ 25 октября 2009
$ 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

Для перевода строки, я оставляю это вам делать.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...