在BASH中的两列中输出文件

时间:2015-06-09 22:57:24

标签: bash

我想在第n行之后重新排列两列中的文件。

例如,假设我有一个这样的文件:

This is a bunch
of text
that I'd like to print
as two
columns starting
at line number 7
and separated by four spaces.
Here are some
more lines so I can
demonstrate
what I'm talking about.

我想像这样打印出来:

This is a bunch           and separated by four spaces.
of text                   Here are some
that I'd like to print    more lines so I can
as two                    demonstrate
columns starting          what I'm talking about.
at line number 7

我怎么能用bash命令或函数做到这一点?

3 个答案:

答案 0 :(得分:2)

实际上,pr几乎可以做到这一点:

pr --output-tabs=' 1' -2 -t tmp1 

This is a bunch                     and separated by four spaces.
of text                             Here are some
that I'd like to print              more lines so I can
as two                              demonstrate
columns starting                    what I'm talking about.
at line number 7  

-2两列; -t省略页眉;如果没有--output-tabs=' 1',它会为它添加的每8个空格插入一个标签。您还可以设置页面宽度和长度(如果您的实际文件长于100行);查看man pr了解一些选项。

如果你修复了“比左边最长的一行多四个空格”,那么也许你可能不得不使用更复杂的东西;

以下内容适用于您的测试输入,但正在达到正确答案的地步,“只需使用Perl;”

#!/bin/sh
infile=${1:-tmp1}
longest=$(longest=0;
          head -n $(( $( wc -l $infile | cut -d ' ' -f 1 ) / 2 )) $infile | \
              while read line
              do
                  current="$( echo $line | wc -c | cut -d ' ' -f 1 )"
                  if [ $current -gt $longest ]
                  then
                      echo $current
                      longest=$current
                  fi
              done | tail -n 1 )
pr -t -2 -w$(( $longest * 2 + 6 )) --output-tabs=' 1' $infile

This is a bunch           and separated by four spa
of text                   Here are some
that I'd like to print    more lines so I can
as two                    demonstrate
columns starting          what I'm talking about.
at line number 7          

...重新阅读你的问题,我想知道你是否意味着你要将nth line字面指定给程序,在这种情况下,上述任何一个都不会起作用,除非该行恰好是半途而废

答案 1 :(得分:1)

谢谢chatraed和BRPocock(和你的同事)。你的回答帮助我思考了这个解决方案,解决了我的需求。

function make_cols
{
     file=$1         # input file
     line=$2         # line to break at
     pad=$(($3-1))   # spaces between cols - 1

     len=$( wc -l < $file )
     max=$(( $( wc -L < <(head -$(( line - 1 )) $file ) ) + $pad ))

     SAVEIFS=$IFS;IFS=$(echo -en "\n\b")

     paste -d" " <( for l in $( cat <(head -$(( line - 1 )) $file ) )
           do
                printf "%-""$max""s\n" $l
           done ) \
           <(tail -$(( len - line + 1 )) $file )

     IFS=$SAVEIFS
}

make_cols tmp1 7 4

答案 2 :(得分:0)

可以通过多种方式进行优化,但可以按要求完成工作。

输入数据(可配置):

  1. 文件
  2. 从第一列的文件借来的行数
  3. 列之间的空格数
  4. <强> format.sh

    #!/bin/bash
    
    file=$1
    if [[ ! -f $file ]]; then
        echo "File not found!"
        exit 1
    fi
    
    spaces_col1_col2=4
    rows_col1=6
    rows_col2=$(($(cat $file | wc -l) - $rows_col1))
    
    IFS=$'\n'
    ar1=($(head -$rows_col1 $file))
    ar2=($(tail -$rows_col2 $file))
    
    maxlen_col1=0
    for i in "${ar1[@]}"; do
        if [[ $maxlen_col1 -lt ${#i} ]]; then
            maxlen_col1=${#i}
        fi
    done
    maxlen_col1=$(($maxlen_col1+$spaces_col1_col2))
    
    if [[ $rows_col1 -lt $rows_col2 ]]; then
        rows=$rows_col2
    else
        rows=$rows_col1
    fi
    
    ar=()
    for i in $(seq 0 $(($rows-1))); do
        line=$(printf "%-${maxlen_col1}s\n" ${ar1[$i]})
        line="$line${ar2[$i]}"
        ar+=("$line")
    done
    
    printf '%s\n' "${ar[@]}"
    

    <强>输出:

    $ > bash format.sh myfile
    This is a bunch           and separated by four spaces.
    of text                   Here are some
    that I'd like to print    more lines so I can
    as two                    demonstrate
    columns starting          what I'm talking about.
    at line number 7
    $ >