Подтвердить что ты не робот

Как переключать/поворачивать каждые две строки с помощью sed/awk?

Я делаю это вручную, и я просто не могу больше этого делать. У меня есть тысячи строк, и я думаю, что это работа для sed или awk.

По существу, у нас есть такой файл:

A sentence X
A matching sentence Y
A sentence Z
A matching sentence N

Этот шаблон продолжается для всего файла. Я хочу перевернуть каждое предложение и соответствующее предложение, чтобы весь файл закончил:

A matching sentence Y
A sentence X
A matching sentence N
A sentence Z

Какие-нибудь советы?

edit: расширение исходной задачи

Димитрий Радулов дал отличный ответ на исходную задачу. Это расширение основной проблемы - еще несколько деталей:

Скажем, у нас есть организованный файл (из-за строки sed, которую дал Dimitre, файл организован). Однако теперь я хочу организовать файл в алфавитном порядке, но только с использованием языка (английского) второй строки.

watashi 
me
annyonghaseyo
hello
dobroye utro!
Good morning!

Я хотел бы организовать в алфавитном порядке английские предложения (каждое второе предложение). Учитывая вышеприведенный ввод, это должен быть выход:

dobroye utro!
Good morning!
annyonghaseyo
hello
watashi
me 
4b9b3361

Ответ 1

sed 'N; 
s/\(.*\)\n\(.*\)/\2\
\1/' infile

N - добавьте следующую строку ввода в пространство шаблонов
\(.*\)\n\(.*\) - сохранить соответствующие части пространства шаблона один до и один после новой строки.
\2\\ \1 - обменять две строки (\ 1 - первая сохраненная часть, \ 2 - второй). Используйте экранированную литеральную новую строку для переносимости

С некоторыми реализациями sed вы можете использовать escape-последовательность \n: \2\n\1.

Ответ 2

Для первой части вопроса, это один из способов обмена каждой другой линией друг с другом в sed без использования регулярных выражений:

sed -n 'h;n;p;g;p'

Командная строка -n подавляет автоматическую печать. Команда h помещает копии текущей строки из пространства шаблонов в пространство удержания, n читает в следующей строке пространство рисунка и p печатает ее; g копирует первую строку из пространства удержания обратно в пространство шаблона, возвращая первую строку в пространство рисунка и p печатает его.

Ответ 3

Первый вопрос:

awk '{x = $0; getline; print; print x}' filename

следующий вопрос: сортировать по 2-й строке

paste - - < filename | sort -f -t $'\t' -k 2 | tr '\t' '\n'

который выводит:

dobroye utro!
Good morning!
annyonghaseyo
hello
watashi
me

Ответ 4

Предполагая входной файл следующим образом:

A sentence X
Z matching sentence Y
A sentence Z
B matching sentence N
A sentence Z
M matching sentence N

Вы можете выполнять обмен и сортировку с помощью Perl:

perl -lne'
 $_{ $_ } = $v unless $. % 2;
 $v = $_;
 END {
  print $_, $/, $_{ $_ }
    for sort keys %_; 
   }' infile

Выход, который я получаю:

% perl -lne'
 $_{ $_ } = $v unless $. % 2;
 $v = $_;
 END {
  print $_, $/, $_{ $_ }
    for sort keys %_;
   }' infile
B matching sentence N
A sentence Z
M matching sentence N
A sentence Z
Z matching sentence Y
A sentence X

Если вы хотите заказать по первой строке (перед обменом):

perl -lne'
 $_{ $_ } = $v unless $. % 2;
 $v = $_;
 END {
  print $_, $/, $_{ $_ }
    for sort {
      $_{ $a } cmp $_{ $b }
      } keys %_; 
   }' infile

Итак, если исходный файл выглядит так:

% cat infile1
me
watashi 
hello
annyonghaseyo
Good morning!
dobroye utro!

Результат должен выглядеть следующим образом:

% perl -lne'
 $_{ $_ } = $v unless $. % 2;
 $v = $_;
 END {
  print $_, $/, $_{ $_ }
    for sort {
  $_{ $a } cmp $_{ $b }
  } keys %_;
   }' infile1
dobroye utro!
Good morning!
annyonghaseyo
hello
watashi 
me

Эта версия должна корректно обрабатывать повторяющиеся записи:

perl -lne'
 $_{ $_, $. } = $v unless $. % 2;
 $v = $_;
 END {
    print substr( $_, 0, length() - 1) , $/, $_{ $_ }
    for sort {
      $_{ $a } cmp $_{ $b }
      } keys %_; 
   }' infile

И еще одна версия, основанная на решении, опубликованном Гленном (включенный обмен записи и предполагающий, что шаблон _ZZ_ отсутствует в текстовом файле):

sed 'N; 
  s/\(.*\)\n\(.*\)/\1_ZZ_\2/' infile | 
    sort |
      sed 's/\(.*\)_ZZ_\(.*\)/\2\
\1/'