Text-Processing

更好的粘貼命令

  • September 10, 2020

我有以下兩個文件(我用點填充了行,因此文件中的每一行都具有相同的寬度,並使 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...

不像原始輸出那樣醜陋,但無論如何按列都是錯誤的。

假設您的文件中沒有任何製表符,

paste file1 file2 | expand -t 13

適當選擇arg 以-t覆蓋 file1 中所需的最大線寬。

OP 增加了一個更靈活的解決方案:

我這樣做是為了讓它在沒有幻數 13 的情況下工作:

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

它不容易鍵入,但可以在腳本中使用。

我認為 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]:""
 }
}

引用自:https://unix.stackexchange.com/questions/98945