У меня есть текстовый файл ("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.
Это должно сделать работу (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)"
Вот еще одно решение: (предполагается набор символов, в котором ':' - это восьмеричный 72, например, ascii)
perl -l72 -pe '$\="\n" if eof' INPUT.TXT