Найдите (и разделите) общие начальные пробелы из файла / трубы

Я ищу способ найти и удалить обычные начальные пробелы из текстового потока или файла. Я не хочу удалять все ведущие пробелы (это было бы просто sed 's/^[[:space:]]*//' ). Только сумма, общая для всех, кроме пустых строк .

Пример:

 printf ' some text\n\n some more text\n' | the_awesome_command_or_script 

должен печатать

 some text some more text 

Прогресс:

Я знаю, что можно использовать такие инструменты, как awk или shell, в while цикл для первого цикла по всем строкам и подсчет начального пробела, а затем можно удалить пробелы с помощью динамически созданной команды sed.

Скрипт awk для подсчета пробелов может выглядеть примерно так

 awk 'BEGIN { amount = 0 } /^[^[:space:]]/ { print 0; exit } /^$/{ next } /^[[:space:]]/ { amount = match($0, "[^[:space:]]") - 1 } END { print amount }' 

Но тогда мне нужен временный файл, и мой скрипт будет выглядеть так:

 generate_some_text | cat > tempfile amount=$(above_awk_script < tempfile) sed "s/^[[:space:]]\{$amount\}//" < tempfile rm tempfile 

Вопросов:

Есть ли инструмент, который лучше подходит для этой работы? Могу ли я изменить скрипт, чтобы избавиться от временного файла?

реальность:

Я пытаюсь улучшить свою запись mailcap для text/html если запрашивается copiousoutput : в настоящее время это text/html; elinks -no-home -dump %s; nametemplate=%s.html; copiousoutput; text/html; elinks -no-home -dump %s; nametemplate=%s.html; copiousoutput; но, как вы могли догадаться, я хочу избавиться от некоторых начальных пробелов. Может быть, я просто слишком усердно думаю, и для этого есть очень простое решение?

2 Solutions collect form web for “Найдите (и разделите) общие начальные пробелы из файла / трубы”

Поскольку это либо все пробелы, либо все вкладки, вы можете

 sed 'H;$!d;g;: m;/\n[^\n[:blank:]]/!s/\n[^\n]/\n/g;tm;s/.//' 

Это gnu sed (я не думаю, что поддержка другого sed [\n] ). Он работает, добавляя каждую строку в старый буфер H и затем выставляя ее, если она не последняя ( $! ). В последней строке он копирует содержимое пространства пробелов по пространству шаблона через g (содержимое пространства шаблонов начинается с \n ewline).
Затем он удаляет первый символ в каждой строке ( s/\n[^\n]/\n/g ), если строка в пространстве шаблонов не начинается с пробела ( /\n[^\n[:blank:]]/! ). После каждой успешной замены она возвращается к метке m . Если есть хотя бы одна строка в пространстве шаблонов, которая начинается с s/.// она просто удаляет ведущую s/.// новой строки из пространства шаблонов ( s/.// ), а затем автоматически распечатывает ее.

если вы беспокоитесь только о первой строке вывода, то ограничивайте, на что указывает sed, только по адресу линии 1:

printf ' some text\n\n some more text\n' |sed '1s/^[ \t]*\([^ \t]\+.*\)$/\1/'

это игнорирует любое пустое пространство в начале, а затем сопоставляется с чем-либо, что не является пробелом плюс остальная часть строки и только в строке 1.

  • Regex ищет корни слова с общими префиксами
  • sed - не добавляет новую строку EOF и заменяет букву не определенной
  • Извлечение строк из файла в зависимости от других строк
  • Извлечь определенное значение из блоков данных
  • Как grep / awk / sed для текста в журнале и отображать кусок с текстом?
  • Вырезание текста между двумя запятыми, исключая последующий текст
  • Делайте более длинные строки из подстрок, сохраняя новую строку между каждой строкой
  • Греп, чтобы найти правильную строку, sed, чтобы изменить содержимое, а затем вернуть его в исходный файл?
  • Проблема с sed-подстановкой в ​​многословном регулярном выражении
  • GNU Найти это, но не так и сделать Sed?
  • Проблема с форматированием даты «sed»
  • Linux и Unix - лучшая ОС в мире.