UNIX: Замените Новую строку w/Двоеточие, Сохранив Новую строку Перед EOF

У меня есть текстовый файл ("INPUT.txt") формата:

A<LF>
B<LF>
C<LF>
D<LF>
X<LF>
Y<LF>
Z<LF>
<EOF>

к которому я должен переформатировать:

A:B:C:D:X:Y:Z<LF>
<EOF>

Я знаю, что можно сделать это с 'sed'. Существует миллиард хитов Google для того, чтобы сделать это с 'sed'. Но я пробую к удобочитаемости акцента, простоте, и использую корректный инструмент для корректного задания. 'sed' является строчным редактором, который использует и скрывает новые строки. Вероятно, не правильный инструмент для этого задания!

Я думаю, что корректный инструмент для этого задания был бы 'TR'. Я могу заменить все новые строки двоеточиями с командой:

cat INPUT.txt | tr '\n' ':'

Существует 99% моей сделанной работы. У меня есть проблема, теперь, все же. Путем замены всех новых строк двоеточиями я не только получаю постороннее двоеточие в конце последовательности, но и я также теряю возврат каретки в конце входа. Это похоже на это:

A:B:C:D:X:Y:Z:<EOF>

Теперь, я должен удалить двоеточие из конца входа. Однако, если я пытаюсь передать этот обработанный вход через 'sed' для удаления заключительного двоеточия (который был бы теперь, я думаю, быть надлежащим использованием 'sed'), я оказываюсь со второй проблемой. Вход больше не завершается новой строкой вообще! 'sed' перестал работать напрямую для всех команд, потому что он никогда не находит конец первой строки входа!

Кажется, что добавление новой строки в конец некоторого входа очень, очень общая задача, и рассмотрение I самостоятельно просто очень испытало желание записать программу, чтобы сделать это в C (который возьмет приблизительно восемь строк кода), я не могу предположить, что уже нет очень простого способа сделать это с инструментами, уже доступными Вам в ядре Linux.

10
задан Josh Darnell 13 January 2012 в 15:13
поделиться

2 ответа

Это должно сделать работу (cat и echo не нужны):

tr '\n' ':' < INPUT.TXT | sed 's/:$/\n/'

Используя только sed:

sed -n ':a; $ ! {N;ba}; s/\n/:/g;p' INPUT.TXT

Bash без экстерналов:

string=($(<INPUT.TXT))
string=${string[@]/%/:}
string=${string//: /:}
string=${string%*:}

Использование цикла в sh:

colon=''
while read -r line
do
    string=$string$colon$line
    colon=':'
done < INPUT.TXT

Использование AWK:

awk '{a=a colon $0; colon=":"} END {print a}' INPUT.TXT

Или:

awk '{printf colon $0; colon=":"} END {printf "\n" }' INPUT.TXT

Edit:

Вот другой способ в чистом Bash:

string=($(<INPUT.TXT))
saveIFS=$IFS
IFS=':'
newstring="${string[*]}"
IFS=$saveIFS

Edit 2:

Вот еще один способ, который does использует echo:

echo "$(tr '\n' ':' < INPUT.TXT | head -c -1)"
16
ответ дан 3 December 2019 в 20:03
поделиться

Вот еще одно решение: (предполагается набор символов, в котором ':' - это восьмеричный 72, например, ascii)

perl -l72 -pe '$\="\n" if eof' INPUT.TXT
1
ответ дан 3 December 2019 в 20:03
поделиться
Другие вопросы по тегам:

Похожие вопросы: