Как преобразовать многострочный в однострочный, но сохранить параграфы

find $DIR -depth -maxdepth 3 \
    -type d -readable -printf \
    'printf "\\n%p\\n"
    ls -t --color=always "%p"\n' |\
    . /dev/stdin 2>&-

Это позволяет избежать проблем со списком аргументов, потому что единственный аргумент ls , который когда-либо получит, - это имя каталога, который вы хотите перечислить. Вы можете делать это с чем угодно.

Оболочка всего . sources | pipe в качестве сценария оболочки - это тот же процесс, и у него нет проблем, которые могут возникнуть при вызове execve .

В любом случае - вышеупомянутое касается только трех глубин, которые можно регулировать путем изменения maxdepth . Он также сначала глубоко - так что вы продвигаетесь назад к текущему каталогу с глубины .

Вы также можете заметить, что получаете $ LSCOLORS - на моей машине он также предоставляет аккуратно напечатанные столбцы и все остальное, что вам нужно от ls - или, если на то пошло, все, что вы могу представить, что вы хотите использовать . источник.

NO SVN

Опять же, это сделает все, что вы ожидаете от ls . Таким образом, скрыть файлы .svn так же просто, как изменить строку ls на:

ls -t --color=always --hide="*svn" "%p"\n

Или, если вы хотите видеть svn расширения в каждой папке НО ./ svn вы можете изменить его так, чтобы вся команда выглядела так:

    find $DIR -depth -maxdepth 3 \
        -type d -readable -printf \
            'printf "\\n%p\\n" ; hide=
            [ "%p" = "./svn" ] && hide="*svn"
            ls -t --color=always --hide="$hide" "%p"\n' |\
    . /dev/stdin 2>&-

Лично мне нравится ls -s и, если вам интересно, - u будет сортировать по времени доступа, а не по времени модификации.

0
01.11.2018, 23:48
3 ответа

perlимеет режим абзаца через флаг -00perlrun, поэтому, если мы заменим все внутренние новые строки вашего inputпробелом:

$ wc -l input
       7 input
$ perl -00 -pe 's/\n(?!\Z)/ /g' input | wc -l
       3
$ 

Бит (?!\Z)не заменяет новые строки в конце каждого абзаца, тем самым сохраняя границы абзаца.

Другой вариант — lex. Это раскрывает несколько сложных моментов, в частности, как обрабатывать EOFи всегда ли включать конечную новую строку (, как того требует POSIX ), и то, что вы определяете как абзац :, ровно две новые строки или любое другое число. ?

%%

[\n][\n]+ { printf("%s", yytext); }
\n        { int c = input();
            /* TODO book docs say this should return EOF on EOF ?? */
            if (c == 0) {
                putchar('\n');
                yyterminate();
            } else {
                printf(" %c", c);
            }
          }
<<EOF>>   { putchar('\n'); yyterminate(); }

%%

int main(int argc, char *argv[])
{
    return yylex();
}

Вероятно, требуется больше тестов, чем

$ make paranlneg
lex  -o lex.paranlneg.c paranlneg.l
egcc -O2 -pipe    -o paranlneg lex.paranlneg.c  -ll
rm -f lex.paranlneg.c
$ perl -E 'say "a\nb\n\nc\nd"' |./paranlneg
a b

c d
$ 
3
28.01.2020, 02:14

Аналогичен ответу @thrig's Perl -на основе , но с использованием GNU Awk:

$ gawk -vRS= '{$1=$1; printf $0 RT}' file.txt
Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Dictum sit amet justo donec enim diam vulputate. Nunc faucibus a pellentesque sit amet.

Quis enim lobortis scelerisque fermentum dui faucibus in. Leo duis ut diam quam nulla porttitor massa id neque. Vitae tortor condimentum lacinia quis vel eros.

Для быстрого решения можно использовать утилиту Coreutils fmtс достаточно большим значением ширины:

fmt -w1000 file.txt

(хотя по умолчанию это будет добавлять двойной пробел после каждой точки ).

2
28.01.2020, 02:14

Подход, основанный на GNU sed:

Вы можете использовать tr, чтобы заменить символы <newline>символами <NUL>, затем использовать sed, чтобы изменить последовательность из двух или более последовательных символов <NUL>в двойной символ <newline>, затем использовать tr. ] для замены оставшихся <NUL>символов пробелами:

$ tr '\n' '\0' <file.txt | sed 's/\o000\{2,\}/\n\n/g' | tr '\0' ' ' | sed --null-data 's/ $/\n/'

Здесь последний sedнужен только для замены последнего оставшегося пробела новой строкой.

В качестве альтернативы (и более кратко )вы можете указать sedрассматривать ваш файл как последовательность строк, заканчивающихся нулем -(, то есть sedсчитает его одной строкой )и замените одним пробелом все вхождения одной новой строки, перед которой и за которой следует не -символ пробела:

$ sed --null-data 's/\([^[:space:]]\)\n\([^[:space:]]\)/\1 \2/g' file.txt

Это также сохранит вертикальный интервал между абзацами, то есть количество последовательных новых строк.Я предпочел искать не -символ пробела (вместо точки ), за которой следует новая строка, просто для обработки случая, когда предложение не заканчивается точкой.

2
28.01.2020, 02:14

Теги

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