2015-04-17 5 views
1

Использование sed, как я могу обрезать один или несколько последовательных строк только с нуля и/или конца файла? (Под «пробельные только», я имею в виду строки, которые не содержат каких-либо не-пробельных символов, то есть линии, которые являются пустым или содержать только пробельные символы.)Как обрезать последовательные пробелы от начала/конца файла через sed

Например, если мой файл:

<blank line> 
<line only containing some space/tab characters> 
<blank line> 
foo 
bar 
<tab character> 
baz 
<space character> 
<space character><tab character> 
qux 
<tab character> 

то желаемый результат будет:

foo 
bar 
<tab character> 
baz 
<space character> 
<space character><tab character> 
qux 

Если зачистка от начала и конца файла должно осуществляться в отдельных sed заклятий, это нормально, хотя я бы также быть заинтересован в решениях, которые управляют его все в пределах одного вызова.

P.S. Это легко в Perl/Ruby и т. Д., Но я хотел бы узнать, возможно ли это в sed. Благодаря!

+0

Вы хотите удалить все пробелы только в виде пробелов, но оставить одиночные только пробелы? –

+0

Нет, одиночные строки с пробелами в начале и конце файла также должны быть обрезаны. –

+0

Это не совсем ответит на вопрос. Должны быть удалены одиночные ws-only строки в середине файла? Должны ли последовательные строки ws-only в середине файла сворачиваться в одну строку или удаляться? Все строки ws-only в начале и в конце должны быть удалены, что кажется очевидным. –

ответ

2

Я не вижу каких-либо реальных SED специалисты выскакивают с решением еще так вот моя попытка (GNU СЭД конкретных из-за \S и \s - заменить [^[:space:]] и [[:space:]] соответственно для POSIX):

$ sed -e '/\S/,$!d' -e :a -e '/^\s*$/{$d;N;ba' -e '}' file 
foo 
bar 

baz 


qux 

и в случае, если кто-то хочет видеть разумный подход, чтобы сравнить с любым арканом СЕПГА колдовства, в конечном счете вызывается, вот один из способов использования GNU AWK для мульти-полукокса RS и \s аббревиатуры для [[:space:]]:

$ awk -v RS='^$' '{gsub(/^\s+|\s+$/,"")}1' file 
foo 
bar 

baz 


qux 

POSIX-эквивалент, если вы счастливы выбрать некоторый элемент управления, который, как вы знаете, не может быть на вашем входе (например, используя ^C = буквального control-C полукокс):

awk -v RS='^C' '{gsub(/^[[:space:]]+|[[:space:]]+$/,"")}1' file 

иначе:

awk '{rec=rec $0 RS} END{gsub(/^[[:space:]]+|[[:space:]]+$/,"",rec); print rec}' file 

или, если вы ограничены в памяти и не могу читать весь файл сразу нужно 2 прохода, чтобы определить, где последний не -blank линия, например:

awk 'NR==FNR{if(NF){if(!beg)beg=NR; end=NR}; next} (FNR>=beg)&&(FNR<=end)' file file 

или вы должны буферами пустых строк (после первоначального набора из них), пока не ударил, не пустую строку, а затем распечатать, что буфер Befo re Текущая строка:

awk 'NF{printf "%s%s\n",buf,$0; buf=""; f=1; next} f{buf = buf $0 RS}' file 
+1

Ничего, но как бы вы это сделали с ванильным POSIX awk? –

+1

Я добавил пару эквивалентов POSIX. –

+1

Отлично, спасибо! Это также должно быть возможно без необходимости дублировать более одного абзаца в память за раз, но я не стал это выполнять. –

Смежные вопросы