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
- или, если на то пошло, все, что вы могу представить, что вы хотите использовать . источник.
Опять же, это сделает все, что вы ожидаете от 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
будет сортировать по времени доступа, а не по времени модификации.
perl
имеет режим абзаца через флаг -00
perlrun
, поэтому, если мы заменим все внутренние новые строки вашего 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
$
Аналогичен ответу @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
(хотя по умолчанию это будет добавлять двойной пробел после каждой точки ).
Подход, основанный на 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
Это также сохранит вертикальный интервал между абзацами, то есть количество последовательных новых строк.Я предпочел искать не -символ пробела (вместо точки ), за которой следует новая строка, просто для обработки случая, когда предложение не заканчивается точкой.