Как переключать/поворачивать каждые две строки с помощью 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
Ответы
Ответ 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/'