より良い貼り付けコマンド

より良い貼り付けコマンド

次の2つのファイルがあります。ファイルの各行が同じ幅を持つように行をドットで埋め、より明確にするために、file1をすべて大文字にしました。

contents of file1:

ETIAM......
SED........
MAECENAS...
DONEC......
SUSPENDISSE

contents of file2

Lorem....
Proin....
Nunc.....
Quisque..
Aenean...
Nam......
Vivamus..
Curabitur
Nullam...

file2 は file1 より長くなります。

このコマンドを実行するとき:

paste file1 file2

私はこの出力を得る

ETIAM...... Lorem....
SED........ Proin....
MAECENAS... Nunc.....
DONEC...... Quisque..
SUSPENDISSE Aenean...
    Nam......
    Vivamus..
    Curabitur
    Nullam...

次のように出力するにはどうすればよいですか?

ETIAM...... Lorem....
SED........ Proin....
MAECENAS... Nunc.....
DONEC...... Quisque..
SUSPENDISSE Aenean...
            Nam......
            Vivamus..
            Curabitur
            Nullam...

頑張った

paste file1 file2 | column -t

しかし、これは次のようになります。

ETIAM......  Lorem....
SED........  Proin....
MAECENAS...  Nunc.....
DONEC......  Quisque..
SUSPENDISSE  Aenean...
Nam......
Vivamus..
Curabitur
Nullam...

元の出力ほど醜いことはありませんが、とにかく間違った列です。

答え1

ファイルにタブ文字がないと仮定すると、

paste file1 file2 | expand -t 13

-tfile1に必要な最大行幅を含めるには、argを適切に選択します。

OPはより柔軟なソリューションを追加しました。

私はマジックナンバー13なしで動作するようにしました。

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

入力するのは簡単ではありませんが、スクリプトで使用できます。

答え2

私はawkが良いことをすることができると思い、「awk 2つのファイルから入力を読み込んでいます」を検索して見つけました。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 [email protected]
# 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]:""
  }
}

答え3

Debian とその派生物にはcolumn次のものがあります。-n のもがい空のフィールドで列が正しく機能するようにするオプションです。内部的には、ワイド文字列を引数のワイド文字で区切られたトークンに分割するcolumnこの関数が使用されます。wcstok(wcs, delim, ptr)delim

wcstokdelimマークを認識する前に、まず広い文字をスキップしてください。このオプション-nで使用されるアルゴリズムはスキップされませんdelim

残念ながら、これは移植性が悪いです。-nこれは Debian 専用で、columnPOSIX にはなく、明らかに BSD です。

答え4

パディングポイントを削除する:

ファイル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

関連情報