Я пытаюсь изменить порядок линий в определенном порядке. Работа с файлом с несколькими строками (например, 99 строк). Для каждых трех строк я бы хотел, чтобы вторая строка была третьей строкой, а третья - второй строкой.
ПРИМЕР.
1- вход:
gi_1234
My cat is blue.
I have a cat.
gi_5678
My dog is orange.
I also have a dog.
...
2- Выход:
gi_1234
I have a cat.
My cat is blue.
gi_5678
I also have a dog.
My dog is orange.
...
linux
text-processing
command-line
Анник Рэймонд
источник
источник
NR%3 == 0 { print; print delay; delay=""} END { if(length(delay) != 0 ) { print delay }
.То есть,
p
наберите текущую строку, получитеn
ext,h
старую ее, получитеn
extG
и т. Д.p
Удерживаемую строку (добавьте ее в пространство шаблона) и наберите это двухстрочное пространство шаблона с заменой третьей и второй строк.источник
Другой подход к awk :
Выход:
(getline L2)>0 && (getline L3)>0
- извлекает следующие 2 записи, если они существуюткаждая 2-я и 3-я записи назначаются
L2
иL3
переменным соответственноисточник
line2
и т. Д.Использование
perl
и короткий скрипт:Сценарий обрабатывает весь файл, для каждой строки (сохраненной в
$_
) он получает следующие две строки ($l2
и$l3
) и печатает их в требуемом порядке: line1, line3, line2.источник
Один из способов может быть следующим:
С другой стороны,
Результаты
источник
Почему бы просто не сделать цикл времени? В развернутом виде:
В «однострочном формате»:
Выходы:
источник
Perl
Идея здесь в том, что мы используем оператор по модулю
%
с$.
переменной номера строки , чтобы выяснить, какой из них является первым, какой - каждой второй, а какой - каждой третьей строкой. Для каждой третьей строки остаток равен 0, а для каждой 1-й и 2-й строки он будет иметь соответствующие номера.Тестовое задание:
Незначительное улучшение
Подход с сохранением второй строки в переменной имеет недостаток. Что, если последняя строка является «второй», то есть для этого номера строки остаток равен 2? Исходный код в ответах my и DopeGhoti не будет напечатан,
My dog is orange
если мы пропустим последнюю строку. Исправление для этого в обоих случаях заключается в использованииEND{}
блока кода с отменой установки временной переменной после печати. Другими словами:и
Таким образом, код будет работать для произвольного числа строк в файле, а не только для тех, которые делятся на 3.
Дополнительное исправление для проблемы, упомянутой в комментариях
В случае awk, если последняя строка в файле выдает 1 для $. % 3, предыдущий код имеет проблему вывода пустого символа новой строки из-за безусловной печати
END{print delay}
, посколькуprint
функция, упомянутая в комментариях, всегда добавляет символ новой строки к любой переменной, с которой она работает. В случаеperl
версии эта проблема не возникает, так как функция-ne
flagsprint
не добавляет символ новой строки.Тем не менее, исправление в случае с awk состоит в том, чтобы сделать его условным, как упомянул Dope Ghoti в комментариях, чтобы проверить длину временной переменной. Версия того же исправления для Perl:
источник
awk
)NR%3 == 0 { print; print delay; delay=""} END { if(length(delay) != 0 ) { print delay }
.-ne
флагами не выводит символ новой строки. Он действительно печатает, но это пустая строка, без завершающей строки. Тем не менее, я добавил упоминание о проблеме и то же исправление в свой ответ. Благодарность !напор
Не подходит для длинных файлов, но все же удобно, если вы просто редактировали файл и хотели, например, изменить порядок некоторых разделов yaml.
Сначала запишите макрос:
И затем повторите желаемое количество раз:
Или просто например
Объяснение:
источник
@q @q @q
можно делать таким образом3@q
- повторить три раза.100@q
- повторить макрос 100 раз.Использование:
./shuffle_lines.awk input.txt
Проверьте shebang
#!/usr/bin/awk -f
, потому чтоawk
местоположение может отличаться в вашей системе.источник