попробуйте это ...
awk '{F=0;for(i=2;i<=NF;i++){if($(i-1)~/TODO/){F=1}if(F){printf("%s ",$i)}}printf("\n")}' RS="D/" tasks.txt | awk '{print > $NF".txt"}'
Решение, которое я использовал, было.
< file.txt sed '$!G' | paste -sd '\\n' -
sed '$!G'
добавляет пустую строку к каждой строке ввода, кроме последней ($
). paste -sd '\\n'
вставляет полученные строки попеременно с обратной косой чертой и n
. И добавляет новую строку в конце, чтобы привести к правильному текстовому выводу. Остерегайтесь нескольких особых случаев, которые вам, возможно, придется здесь рассмотреть. Возьмем для примера 4 файла:
file1
пустой файл file2
файл с одной новой строкой ( )символ (одна пустая строка)file3
правильный текстовый файл, например:
foo
bar
file4
файл с последней строкой без разделителя -:
foo
bar
Если хочешь:
file1
:пустойfile2
:\n
file3
:foo\nbar\n
file4
:foo\nbar
(, например, чтобы вы могли восстановить файл, передав вывод вprintf %b
).
Тогда можно:
perl -pe 's/\n/\\n/; END{print "\n" if $.}' < file
Или с GNUawk
:
gawk '{printf "%s", $0 (RT ? "\\n" : "")}
END{if (NR) print ""}' < file
Вы можете адаптироваться, если хотите игнорировать разделитель последней строки, если он есть, или не хотите завершающую новую строку, но тогда вы можете проверить эти 4 разных случая, когда он делает то, что вы хотите, как вы' Вероятно, вы обнаружите, что для некоторых из них вам необходимо специальное лечение.
Например, ваш
< file sed '$!G' | paste -sd '\\n' -
решение игнорировать разделитель последней строки дает одну пустую строку как для file1
, так и для file2
(, а также для -неправильно разделенного текста -(file4
)может работать неправильно со всеми sed
/ paste
реализации предназначены для работы с действительным текстом ).
perl -pe 's/\n?$/eof ? "\n" : "\\n"/e' < file
может быть более портативным и, возможно, немного лучше для file1
и file2
, которые он оставил бы нетронутыми.
tr
сам по себе не может этого сделать, так как вам нужно заменить один символ на два символа. sed
в одиночку не может сделать это легко, так как он выводит новую строку в конце всего, что печатает. Но вы можете сделать это, объединив два :добавить \n
в конце каждой строки, а затем удалить разрывы строк.
sed 's/$/\\n/' | tr -d '\n'
Это создает файл, оканчивающийся на \n
без разрыва строки. Если вам нужна новая строка в самом конце, выведите ее:
{ sed 's/$/\\n/' | tr -d '\n'; echo; }
(Обратите внимание, что это превращает пустой файл в файл с одной пустой строкой. )Если тебе не нужен последний \n
, отдай его:
sed 's/$/\\n/' | tr -d '\n' | sed 's/\\n$//'
Использование кувалды Perl:
$ perl -pe 's/\n/\\n/' < file.txt ; echo
echo
предназначен для печати завершающей новой строки на тот случай, если это необходимо для целей отображения. Это также изменяет NL в последней строке на \n
.
Или довольно простое решение только в Bash, предполагая, что файл не содержит встроенных байтов NUL. Обратите внимание, что это загружает весь файл в память :
.$ IFS= read -r -d '' text < file.txt; printf '%s\n' "${text//$'\n'/\\n}"