Лучшая команда вставки

Еще один способ включить буферизующий строку режим вывода для long_running_command должен использовать script управляйте что выполнения Ваш long_running_command в псевдотерминале (имущество).

script -q /dev/null long_running_command | print_progress      # FreeBSD, Mac OS X
script -c "long_running_command" /dev/null | print_progress    # Linux
11
06.11.2013, 01:22
6 ответов

Принятие Вас не имеет никаких символов табуляции в Ваших файлах,

paste file1 file2 | expand -t 13

с аргументом к -t соответственно выбранный для покрытия желаемой макс. ширины строки в file1.

OP добавила более гибкое решение:

Я сделал это так, это работает без магического числа 13:

paste file1 file2 | expand -t $(( $(wc -L <file1) + 2 ))

Это не легко ввести, но может использоваться в сценарии.

17
27.01.2020, 19:57

Я думал, что awk мог бы сделать это приятно, таким образом, я погуглил "awk чтение входа из двух файлов" и нашел, что статья о stackoverflow использовала в качестве начальной точки.

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

awk '{if(length($0)>max)max=length($0)}
FNR==NR{s1[FNR]=$0;next}{s2[FNR]=$0}
END { format = "%-" max "s\t%-" max "s\n";
  numlines=(NR-FNR)>FNR?NR-FNR:FNR;
  for (i=1; i<=numlines; i++) { printf format, s1[i]?s1[i]:"", s2[i]?s2[i]:"" }
}' file1 file2

И вот полностью зарегистрированная версия вышеупомянутого.

# 2013-11-05 mike@diehn.net
# Invoke thus:
#   awk -f this_file file1 file2
# The result is what you asked for and the columns will be
# determined by input file order.
#----------------------------------------------------------
# No matter which file we're reading,
# keep track of max line length for use
# in the printf format.
#
{ if ( length($0) > max ) max=length($0) }

# FNR is record number in current file
# NR is record number over all
# while they are equal, we're reading the first file
#   and we load the strings into array "s1"
#   and then go to the "next" line in the file we're reading.
FNR==NR { s1[FNR]=$0; next }

# and when they aren't, we're reading the
#   second file and we put the strings into
#   array s2
{s2[FNR]=$0}

# At the end, after all lines from both files have
# been read,
END {
  # use the max line length to create a printf format
  # the right widths
  format = "%-" max "s\t%-" max "s\n"
  # and figure the number of array elements we need
  # to cycle through in a for loop.
  numlines=(NR-FNR)>FNR?NR-FNR:FNR;
  for (i=1; i<=numlines; i++) {
     printf format, s1[i]?s1[i]:"", s2[i]?s2[i]:""
  }
}
4
27.01.2020, 19:57
  • 1
    +1 это - единственный ответ, который действительно работает с произвольным входом (т.е. со строками, которые могут содержать вкладки). Я не думаю, что это могло быть значительно совершенствовано/улучшено. большое спасибо –  don_crissti 15.02.2017, 23:21

Не очень хорошее решение, но я смог сделать это использование

paste file1 file2 | sed 's/^TAB/&&/'

где ВКЛАДКА заменяется символом табуляции.

2
27.01.2020, 19:57
  • 1
    Из чего роль && в команде sed? –  coffeMug 05.11.2013, 16:57
  • 2
    сингл & помещает то, что разыскивается (вкладка в этом случае). Эта команда просто заменяет вкладку вначале двумя вкладками. –  unxnut 05.11.2013, 17:59
  • 3
    я должен был измениться TAB кому: \t сделать эту работу в zsh на Ubuntu debian. И это действительно только работает, если file1 имеет меньше чем 15 символов –  rubo77 30.11.2013, 08:53

На Debian и производных, column имеет a -n опция nomerge, которая позволяет столбцу делать правильную вещь с пустыми полями. Внутренне, column использование wcstok(wcs, delim, ptr) функция, которая разделяет строку широкого символа на маркеры, разграниченные широкими символами в delim аргумент.

wcstok запускается путем пропуска широких символов в delim, прежде, чем распознать маркер. -n опция использует алгоритм, который не пропускает начальные широкие символы в delim.

К сожалению, это не очень портативно: -n Debian-конкретно, и column не находится в POSIX, это - по-видимому, вещь BSD.

2
27.01.2020, 19:57

awk решение, которое должно быть довольно портативным, и должно работать на произвольное число входных файлов:

# Invoke thus:
#   awk -F\\t -f this_file file1 file2

# every time we read a new file, FNR goes to 1

FNR==1 {
    curfile++                       # current file
}

# read all files and save all the info we'll need
{
    column[curfile,FNR]=$0          # save current line
    nlines[curfile]++               # number of lines in current file
    if (length > len[curfile])
            len[curfile] = length   # max line length in current file
}

# finally, show the lines from all files side by side, as a table
END {
    # iterate through lines until there are no more lines in any file
    for (line = 1; !end; line++) {
            $0 = _
            end = 1

            # iterate through all files, we cannot use
            #   for (file in nlines) because arrays are unordered
            for (file=1; file <= curfile; file++) {
                    # columnate corresponding line from each file
                    $0 = $0 sprintf("%*s" FS, len[file], column[file,line])
                    # at least some file had a corresponding line
                    if (nlines[file] >= line)
                            end = 0
            }

            # don't print a trailing empty line
            if (!end)
                    print
    }
}
1
27.01.2020, 19:57
  • 1
    [ссылки], Как Вы используете это на file1 и file2? Я назвал сценарий paste-awk и попробованный paste file1 file2|paste-awk и я попробовал awk paste-awk file1 file2 но ни один не работал. –  rubo77 30.11.2013, 09:04
  • 2
    я добираюсь awk: Line:1: (FILENAME=file1 FNR=1) Fatal: Division by zero –  rubo77 30.11.2013, 09:04
  • 3
    @rubo77: awk -f paste-awk file1 file2 должен работать, по крайней мере, для GNU awk и mawk. спасибо –  ninjalj 02.12.2013, 12:32
  • 4
    Это работает, хотя это немного отличается от paste между этими двумя строками существует меньше пространства. И если входной файл не будет иметь всех строк та же длина, то он приведет к строке –  rubo77 02.12.2013, 16:14
  • 5
    @rubo77: разделитель полей может быть установлен с -F\\t –  ninjalj 02.12.2013, 17:30

Удаление точек, которые вы использовали для заполнения:

файл1:

ETIAM
SED
MAECENAS
DONEC
SUSPENDISSE

файл2:

Lorem
Proin
Nunc
Quisque
Aenean
Nam
Vivamus
Curabitur
Nullam

Попробуйте следующее:

$ ( echo ".TS"; echo "l l."; paste file1 file2; echo ".TE" ) | tbl | nroff | more

И вы получите:

ETIAM         Lorem
SED           Proin
MAECENAS      Nunc
DONEC         Quisque
SUSPENDISSE   Aenean
              Nam
              Vivamus
              Curabitur
              Nullam
2
27.01.2020, 19:57

Теги

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