Команда как 'столбец-t', который вместо этого сохраняет разделители в выводе

Нет. Менеджер дисплея не обязательно связан с чем-либо еще, что это работает на том же X-сервере. Менеджер по оформлению работает перед входом в систему; это выбрано системным администратором. Все остальное (менеджер окон, менеджер сеансов, настольная среда, …) выбрано пользователем. Не должно даже быть менеджера по оформлению: если Вы входите в систему в текстовом режиме и запускаете GUI с startx, никакой менеджер по оформлению не вовлечен.

Можно проверить, какой менеджер по оформлению является по умолчанию в системе. Это только даст правильный ответ под некоторыми распространенными, но не универсальные предположения. При ручном выполнении другого менеджера по любой причине этот метод не скажет Вам.

Хорошая ставка должна узнать идентификатор процесса X-сервера: его родительский процесс является, вероятно, менеджером по оформлению, если существует тот. Это требует, чтобы Ваши клиенты работали на той же машине как X-сервер. lsof /tmp/.X11-unix/X${DISPLAY#:} покажет процесс X-сервера (принимающий X сокетов, живых в /tmp/.X11-unix).

x=$(lsof -F '' /tmp/.X11-unix/X0); x=${x#p}
ps -p $(ps -o ppid -p $x)

(Объяснение: lsof -F '' вывод печати как p1234. -F опция означает выходной формат машины-parseable, и '' средства только распечатать PID, с буквой p перед ним. x=${x#p} снимает изоляцию с первой буквы p. Последняя строка получает PID родителя X-сервера (ps -o ppid -p $x), и вызовы ps показать информацию о том родительском процессе.)

Некоторые дистрибутивы позволяют устанавливать несколько менеджеров по оформлению. Только будет единственное выполнение, если у Вас не будет системы мультиместа все же. Перечислять все установленные пакеты менеджера по оформлению под Debian и производными:

aptitude -F %p search '~i ~P^x-display-manager$'

или

17
14.08.2011, 12:45
6 ответов

Не уверенный, если я понимаю право, какова Ваша проблема. Но, это может быть решено, добавив дополнительный временный разделитель? следовательно можно использовать второй разделитель для маркировки разделений, сохраняя исходный разделитель нетронутым.

Посмотрите этот пример, где я добавляю к каждому из "|", таким образом, вход команды столбца был бы "xxx | yyyy". Столбец обработает хранение "|" нетронутый:

~$ echo "foo | this is some text | bar" | sed 's/|/@|/g'  | column -s '@' -t
foo   | this is some text   | bar
17
27.01.2020, 19:46
  • 1
    Умный. Почти делает то, что я хочу, и действительно на самом деле делает то, что я спросил - оставляет разделители внутри. Я также хочу, чтобы пробелы рядом с истинными разделителями смогли быть скорректированным вниз, а не просто, как здесь. –  wnoise 14.08.2011, 12:32
  • 2
    @wnoise: использовать sed 's/ *| */@| /g' вместо этого –  Stéphane Gimenez 14.08.2011, 13:45
  • 3
    @Stéphane Gimenez: И добавление sed 's/ |/|/g' после column фиксирует добавленные дополнительные пространства. У нас теперь есть решение, которое работает достаточно хорошо на меня. (Хотя было бы хорошо, если бы это не зависело от дополнительного символа как это. Что, если Вы не доступны?) –  wnoise 14.08.2011, 14:02
  • 4
    @wnoise: Вместо, можно использовать что-то, что обычно не появляется в тексте, как низкое значение ASCII, например, $ '\x01'... (но не $ '\x00')... –  Peter.O 14.08.2011, 17:13

Вот сценарий удара. Это не использует 'столбец-t', и разделитель обрабатывается точно, как IFS, потому что это - IFS (или по крайней мере, внутренняя версия awk IFS)... Разделитель по умолчанию является $' \t'

Этот сценарий полностью увеличивает самое правое поле.
'столбец' не делает этого.
Путем увеличивания всех столбцов этот сценарий может быть
легко измененный для создания кадра таблицы также.

Примечание. Входной файл должен быть обработан дважды
('столбец' должен был бы также сделать это),
Первичная обработка должна получить столбец макс. ширины.
Вторая передача должна развернуть поля (для каждого столбца)

Добавленный некоторые опции и исправил явную ошибку (переименовывающий переменные :(

  • - l Левый пробел для обрезки любых полей с отступом
  • - r Право обрезают пробел шире, чем самый широкий текст (для столбца)
  • - b И-l и-r
  • - L Левый выходной разделитель добавляется
  • - R Правильный выходной разделитель добавляется
  • - B И-L и-R
  • - S Выбирают выходной разделитель

#!/bin/bash
#
#   script [-F sep] [file]
#
#   If file is not specified, stdin is read 
#    
# ARGS ######################################################################
l=;r=;L=;R=;O=;F=' ' # defaults
for ((i=1;i<=${#@};i++)) ;do
  case "$1" in
    -- ) shift 1;((i--));break ;;
    -l ) l="-l";shift 1;((i-=1)) ;;        #  left strip whitespace
    -r ) r="-r";shift 1;((i-=1)) ;;        # right strip whitespace
    -b ) l="-l";r="-r";shift 1;((i-=1)) ;; # strip  both -l and -r whitespace
    -L ) L="-L";shift 1;((i-=1)) ;;        #  Left output delimiter is added
    -R ) R="-R";shift 1;((i-=1)) ;;        # Right output delimiter is added
    -B ) L="-L";R="-R";shift 1;((i-=1)) ;; # output Both -L and -R delimiters
    -F ) F="$2";shift 2;((i-=2)) ;; # source separator
    -O ) O="$2";shift 2;((i-=2)) ;; # output  separator. Default = 1st char of -F 
    -* ) echo "ERROR: invalid option: $1" 1>&2; exit 1 ;;
     * ) break ;;
  esac
done
#
if  [[ -z "$1" ]] ;then # no filename, so read stdin
  f="$(mktemp)"
  ifs="$IFS"; IFS=$'\n'; set -f # Disable pathname expansion (globbing)
  while read -r line; do
    printf "%s\n" "$line" >>"$f"
  done
  IFS="$ifs"; set +f # re-enable pathname expansion (globbing)
else
  f="$1"
fi
[[ -f "$f" ]] || { echo "ERROR: Input file NOT found:" ;echo "$f" ;exit 2 ; }
[[ -z "$F" ]] && F=' '        # input Field Separator string
[[ -z "$O" ]] && O="$F"       # output Field Separator
                 O="${O:0:1}" #   use  single char only

# MAIN ######################################################################
max="$( # get max length of each field/column, and output them
  awk -vl="$l" -vr="$r" -vL="$L" -vR="$R" -vF="$F" -vO="$O" '
    BEGIN { if (F!="") FS=F }
    { for (i=1;i<=NF;i++) { 
        if (l=="-l") { sub("^[ \t]*","",$i) }
        if (r=="-r") { sub("[ \t]*$","",$i) }
        len=length($i); if (len>max[i]) { max[i]=len } 
        if (i>imax) { imax=i } 
      } 
    }
    END { for(i=1;i<=imax;i++) { printf("%s ",max[i]) } }
  ' "$f" 
)"

awk -vl="$l" -vr="$r" -vL="$L" -vR="$R" -vF="$F" -vO="$O" -v_max="$max" '
  BEGIN { if (F!="") FS=F; cols=split(_max,max," ") }
  { # Bring each field up to max len and output with delimiter
    printf("%s",L=="-L"?O:"")
    for(i=1;i<=cols;i++) { if (l=="-l") { sub("^[ \t]*","",$i) } 
                           if (r=="-r") { sub("[ \t]*$","",$i) }
      printf("%s%"(max[i]-length($i))"s%s",$i,"",i==cols?"":O) 
    } 
    printf("%s\n",R=="-R"?O:"")
  }
' "$f"

# END #######################################################################    
if  [[ -z "$1" ]] ;then # no filename, so stdin was used
  rm "$f"   # delete temp file
fi
exit
5
27.01.2020, 19:46
  • 1
    Хорошо сделанный. Конечно, я надеялся на что-то, что на самом деле не потребует записи новой программы. –  wnoise 22.08.2011, 12:58

Смотрите на плагин энергии под названием Tabularize

:Tabularize /<delim>
2
27.01.2020, 19:46

Это было недоступно, когда вы задавали вопрос, но в версии 2.23 столбец из утилит- linux позволяет выбрать разделитель вывода через

   -o, --output-separator string
          Specify the columns delimiter for table output (default is two spaces).

. Просто запустите:

 column -s '|' -o '|' -t infile
6
27.01.2020, 19:46

Использовал идею hmontoliu для реализации простой команды:

#! /bin/bash
delim="${1:-,}"
interm="${2:-\~}"
sed "s/$delim/$interm$delim/g" | column -t -s "$interm" | sed "s/  $delim/$delim/g"

Комментарий:

  • $ {1: -,} - это первый аргумент с , по умолчанию
  • первый sed вставляет промежуточный символ ( $ interm 2-й аргумент или ~ ] по умолчанию)
  • , затем столбец заменяет промежуточный символ пробелами, выполняющими выравнивание
  • , второй sed очищает избыточные пробелы после столбца command

Пример использования:

$ echo "
a: bb: cccc
aaaa: b : cc
" | align :

a   : bb: cccc
aaaa: b : cc

Он также хорош тем, что он идемпотентен: вы можете применить его несколько раз и получить тот же результат (например, при редактировании в vim и повторном выравнивании).

0
27.01.2020, 19:46

Это двухпроходная доработка ответа hmontoliu, которая позволяет избежать необходимости жесткого кодирования разделителя, угадывая его по входным данным.

  1. разобрать входные данные на наличие одиночных неалфавитно-цифровых символов, окруженных пробелами, отсортировать их по наиболее часто встречающимся, и предположить, что наиболее часто встречающийся символ является разделителем, который назначается $d.
  2. действовать более или менее так, как в ответе hmonoliu, но использовать ASCII NULL в качестве вставки вместо @, согласно комментарию PeterO.

Код представляет собой функцию, которая принимает имя файла или другой входной сигнал от STDIN:

algn() { 
    d="$(grep -ow '[^[:alnum:]]' "${1:-/dev/stdin}"  | \
         sort | uniq -c | sort -rn | sed -n '1s/.*\(.$\)/\1/p')" ;
    sed "s/ *$d */\x01$d /g" "${1:-/dev/stdin}"  | column -s $'\001' -t ;
}

Выход algn foo (или также algn < foo):

foo      | bar  | baz
abc def  | 12   | 23456
1
27.01.2020, 19:46

Теги

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