dadlin 08.07.2012 15:19
Есть вопрос! — Как поменять строки местами?
Как в текстовом файле с помощью sed поменять местами 2-ю и 15-ю строки?
cppmm 09.07.2012 08:41 #
+ 1 -
Нужно решение именно на sed? bash+awk/sed или perl не катит?
Не обязательно на sed. Через awk решение попадалось, но выглядело как-то монструозно. А как на perl'e выглядит?
Перл, решение "в лоб", однострочник:
seq 1 20 | perl -e '@lines = ; ($lines[1], $lines[14]) = ($lines[14], $lines[1]); print @lines;'
Разбор полётов:
1) @lines = ; # прочитать строки со стандартного входа в массив,
2) ($lines[1], $lines[14]) = ($lines[14], $lines[1]); # поменять строки местами, индексы начинаются с 0, поэтому 1 и 14, а не 2 и 15,
3) print @lines; # вывести результат.
seq 1 20 | perl -e '@lines = ; ($lines[1], $lines[14]) = ($lines[14], $lines[1]); print @lines;'
Разбор полётов:
1) @lines = ; # прочитать строки со стандартного входа в массив,
2) ($lines[1], $lines[14]) = ($lines[14], $lines[1]); # поменять строки местами, индексы начинаются с 0, поэтому 1 и 14, а не 2 и 15,
3) print @lines; # вывести результат.
seq 1 20 | perl -e '@lines = <STDIN>; ($lines[1], $lines[14]) = ($lines[14], $lines[1]); print @lines;'
Парсер лох, съел угловые скобки.
Само собой не будет работать на бесконечном потоке данных, на большом объёме данных (миллионы строк) будет жрать память и тормозить. В таких случаях надо пересматривать алгоритм.
не буду утверждать что это не возможно, но sed по строчный редактор, он считывает строку, обрабатывает, и передает на выход, т.е перед записью выходного файла надо где-то хранить промежуточные строки.
Ну, теоретически можно sed'ом хватать строку, сохранять во временный файл и потом оттуда забирать, но именно поэтому я и спросил, как с использованием других языков. Но это костыль, имхо.
В седе есть внутренний буфер, так называемый hold-buffer. Ты можешь вырезать 2-ю строку в этот буфер, потом поменять 15-ю строку на сохранённую. Вот только вернуться на 2-ю строку чтобы вставить 15-ю не выйдет.
sed '2h;2d;15x'
sed '2h;2d;15x'
Можно ещё поиграться с командами x (помнять местами холд-буфер) и n (прочитать следующую строку и добавить в буфер строки), но сходу я строку команд не напишу.