A better paste commandAlign text to center with padding on both sidespaste command: setting (multiple) delimitersSelect certain column of of each file, paste to a new fileCompare columns between different filescombine selected column multi fileMatching two main columns at the same time between files, and paste supplementary columns into the output file when those main columns matchMatching 2 main columns between files; and paste other columns into the output file when those main columns match. Keep row size of 1st file intactStrange behavior of pasteArithmetic calculation row-wise for non-fixed column numbershell script /unix commands for text file content editing
Why Is Death Allowed In the Matrix?
How can I make my BBEG immortal short of making them a Lich or Vampire?
Fully-Firstable Anagram Sets
Mage Armor with Defense fighting style (for Adventurers League bladeslinger)
Can I ask the recruiters in my resume to put the reason why I am rejected?
Is it possible to do 50 km distance without any previous training?
Watching something be written to a file live with tail
Why, historically, did Gödel think CH was false?
Why was the small council so happy for Tyrion to become the Master of Coin?
Font hinting is lost in Chrome-like browsers (for some languages )
The Clique vs. Independent Set Problem
Equivalence principle before Einstein
Modeling an IP Address
What does it mean to describe someone as a butt steak?
"You are your self first supporter", a more proper way to say it
Mathematical cryptic clues
Approximately how much travel time was saved by the opening of the Suez Canal in 1869?
Can a Warlock become Neutral Good?
Why doesn't H₄O²⁺ exist?
How can I prevent hyper evolved versions of regular creatures from wiping out their cousins?
How do we improve the relationship with a client software team that performs poorly and is becoming less collaborative?
US citizen flying to France today and my passport expires in less than 2 months
Show that if two triangles built on parallel lines, with equal bases have the same perimeter only if they are congruent.
Why doesn't Newton's third law mean a person bounces back to where they started when they hit the ground?
A better paste command
Align text to center with padding on both sidespaste command: setting (multiple) delimitersSelect certain column of of each file, paste to a new fileCompare columns between different filescombine selected column multi fileMatching two main columns at the same time between files, and paste supplementary columns into the output file when those main columns matchMatching 2 main columns between files; and paste other columns into the output file when those main columns match. Keep row size of 1st file intactStrange behavior of pasteArithmetic calculation row-wise for non-fixed column numbershell script /unix commands for text file content editing
.everyoneloves__top-leaderboard:empty,.everyoneloves__mid-leaderboard:empty,.everyoneloves__bot-mid-leaderboard:empty margin-bottom:0;
I have the following two files ( I padded the lines with dots so every line in a file is the same width and made file1 all caps to make it more clear).
contents of file1:
ETIAM......
SED........
MAECENAS...
DONEC......
SUSPENDISSE
contents of file2
Lorem....
Proin....
Nunc.....
Quisque..
Aenean...
Nam......
Vivamus..
Curabitur
Nullam...
Notice that file2 is longer than file1.
When I run this command:
paste file1 file2
I get this output
ETIAM...... Lorem....
SED........ Proin....
MAECENAS... Nunc.....
DONEC...... Quisque..
SUSPENDISSE Aenean...
Nam......
Vivamus..
Curabitur
Nullam...
What can I do for the output to be as follows ?
ETIAM...... Lorem....
SED........ Proin....
MAECENAS... Nunc.....
DONEC...... Quisque..
SUSPENDISSE Aenean...
Nam......
Vivamus..
Curabitur
Nullam...
I tried
paste file1 file2 | column -t
but it does this:
ETIAM...... Lorem....
SED........ Proin....
MAECENAS... Nunc.....
DONEC...... Quisque..
SUSPENDISSE Aenean...
Nam......
Vivamus..
Curabitur
Nullam...
non as ugly as original output but wrong column-wise anyway.
text-processing columns paste
add a comment |
I have the following two files ( I padded the lines with dots so every line in a file is the same width and made file1 all caps to make it more clear).
contents of file1:
ETIAM......
SED........
MAECENAS...
DONEC......
SUSPENDISSE
contents of file2
Lorem....
Proin....
Nunc.....
Quisque..
Aenean...
Nam......
Vivamus..
Curabitur
Nullam...
Notice that file2 is longer than file1.
When I run this command:
paste file1 file2
I get this output
ETIAM...... Lorem....
SED........ Proin....
MAECENAS... Nunc.....
DONEC...... Quisque..
SUSPENDISSE Aenean...
Nam......
Vivamus..
Curabitur
Nullam...
What can I do for the output to be as follows ?
ETIAM...... Lorem....
SED........ Proin....
MAECENAS... Nunc.....
DONEC...... Quisque..
SUSPENDISSE Aenean...
Nam......
Vivamus..
Curabitur
Nullam...
I tried
paste file1 file2 | column -t
but it does this:
ETIAM...... Lorem....
SED........ Proin....
MAECENAS... Nunc.....
DONEC...... Quisque..
SUSPENDISSE Aenean...
Nam......
Vivamus..
Curabitur
Nullam...
non as ugly as original output but wrong column-wise anyway.
text-processing columns paste
2
paste
is using tabs in front of the lines from second file. You may have to use a postprocessor to align the columns appropriately.
– unxnut
Nov 5 '13 at 14:17
3
paste file1 file2 | column -tn
?
– ninjalj
Nov 5 '13 at 14:18
does file1 always have fixed size columns?
– RSFalcon7
Nov 5 '13 at 14:18
@RSFalcon7 Yes, it does.
– Tulains Córdova
Nov 6 '13 at 0:42
add a comment |
I have the following two files ( I padded the lines with dots so every line in a file is the same width and made file1 all caps to make it more clear).
contents of file1:
ETIAM......
SED........
MAECENAS...
DONEC......
SUSPENDISSE
contents of file2
Lorem....
Proin....
Nunc.....
Quisque..
Aenean...
Nam......
Vivamus..
Curabitur
Nullam...
Notice that file2 is longer than file1.
When I run this command:
paste file1 file2
I get this output
ETIAM...... Lorem....
SED........ Proin....
MAECENAS... Nunc.....
DONEC...... Quisque..
SUSPENDISSE Aenean...
Nam......
Vivamus..
Curabitur
Nullam...
What can I do for the output to be as follows ?
ETIAM...... Lorem....
SED........ Proin....
MAECENAS... Nunc.....
DONEC...... Quisque..
SUSPENDISSE Aenean...
Nam......
Vivamus..
Curabitur
Nullam...
I tried
paste file1 file2 | column -t
but it does this:
ETIAM...... Lorem....
SED........ Proin....
MAECENAS... Nunc.....
DONEC...... Quisque..
SUSPENDISSE Aenean...
Nam......
Vivamus..
Curabitur
Nullam...
non as ugly as original output but wrong column-wise anyway.
text-processing columns paste
I have the following two files ( I padded the lines with dots so every line in a file is the same width and made file1 all caps to make it more clear).
contents of file1:
ETIAM......
SED........
MAECENAS...
DONEC......
SUSPENDISSE
contents of file2
Lorem....
Proin....
Nunc.....
Quisque..
Aenean...
Nam......
Vivamus..
Curabitur
Nullam...
Notice that file2 is longer than file1.
When I run this command:
paste file1 file2
I get this output
ETIAM...... Lorem....
SED........ Proin....
MAECENAS... Nunc.....
DONEC...... Quisque..
SUSPENDISSE Aenean...
Nam......
Vivamus..
Curabitur
Nullam...
What can I do for the output to be as follows ?
ETIAM...... Lorem....
SED........ Proin....
MAECENAS... Nunc.....
DONEC...... Quisque..
SUSPENDISSE Aenean...
Nam......
Vivamus..
Curabitur
Nullam...
I tried
paste file1 file2 | column -t
but it does this:
ETIAM...... Lorem....
SED........ Proin....
MAECENAS... Nunc.....
DONEC...... Quisque..
SUSPENDISSE Aenean...
Nam......
Vivamus..
Curabitur
Nullam...
non as ugly as original output but wrong column-wise anyway.
text-processing columns paste
text-processing columns paste
edited Nov 5 '13 at 23:22
Gilles
546k12911111624
546k12911111624
asked Nov 5 '13 at 14:09
Tulains CórdovaTulains Córdova
5412723
5412723
2
paste
is using tabs in front of the lines from second file. You may have to use a postprocessor to align the columns appropriately.
– unxnut
Nov 5 '13 at 14:17
3
paste file1 file2 | column -tn
?
– ninjalj
Nov 5 '13 at 14:18
does file1 always have fixed size columns?
– RSFalcon7
Nov 5 '13 at 14:18
@RSFalcon7 Yes, it does.
– Tulains Córdova
Nov 6 '13 at 0:42
add a comment |
2
paste
is using tabs in front of the lines from second file. You may have to use a postprocessor to align the columns appropriately.
– unxnut
Nov 5 '13 at 14:17
3
paste file1 file2 | column -tn
?
– ninjalj
Nov 5 '13 at 14:18
does file1 always have fixed size columns?
– RSFalcon7
Nov 5 '13 at 14:18
@RSFalcon7 Yes, it does.
– Tulains Córdova
Nov 6 '13 at 0:42
2
2
paste
is using tabs in front of the lines from second file. You may have to use a postprocessor to align the columns appropriately.– unxnut
Nov 5 '13 at 14:17
paste
is using tabs in front of the lines from second file. You may have to use a postprocessor to align the columns appropriately.– unxnut
Nov 5 '13 at 14:17
3
3
paste file1 file2 | column -tn
?– ninjalj
Nov 5 '13 at 14:18
paste file1 file2 | column -tn
?– ninjalj
Nov 5 '13 at 14:18
does file1 always have fixed size columns?
– RSFalcon7
Nov 5 '13 at 14:18
does file1 always have fixed size columns?
– RSFalcon7
Nov 5 '13 at 14:18
@RSFalcon7 Yes, it does.
– Tulains Córdova
Nov 6 '13 at 0:42
@RSFalcon7 Yes, it does.
– Tulains Córdova
Nov 6 '13 at 0:42
add a comment |
6 Answers
6
active
oldest
votes
Assuming you don't have any tab characters in your files,
paste file1 file2 | expand -t 13
with the arg to -t
suitably chosen to cover the desired max line width in file1.
OP has added a more flexible solution:
I did this so it works without the magic number 13:
paste file1 file2 | expand -t $(( $(wc -L <file1) + 2 ))
It's not easy to type but can be used in a script.
nice! I didn't know about expand before I read your answer :)
– TabeaKischka
Dec 7 '18 at 14:30
add a comment |
I thought awk might do it nicely, so I googled "awk reading input from two files" and found an article on stackoverflow to use as a starting point.
First is the condensed version, then fully commented below that. This took a more than a few minutes to work out. I'd be glad of some refinements from smarter folks.
awk 'if(length($0)>max)max=length($0)
FNR==NRs1[FNR]=$0;nexts2[FNR]=$0
END format = "%-" max "st%-" max "sn";
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
And here is the fully documented version of the above.
# 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 "st%-" max "sn"
# 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]:""
1
+1 this is the only answer that does work with arbitrary input (i.e. with lines that may contain tabs). I don't think this could be significantly refined/improved.
– don_crissti
Feb 15 '17 at 21:21
add a comment |
Not a very good solution but I was able to do it using
paste file1 file2 | sed 's/^TAB/&&/'
where TAB is replaced with the tab character.
What is the role of&&
in the sed command?
– coffeMug
Nov 5 '13 at 14:57
1
A single&
puts what is being searched for (a tab in this case). This command simply replaces the tab at the beginning with two tabs.
– unxnut
Nov 5 '13 at 15:59
I had to changeTAB
tot
to make this work in zsh on Ubuntu debian. And it does only work if file1 has less than 15 chars
– rubo77
Nov 30 '13 at 6:53
add a comment |
On Debian and derivatives, column
has a -n
nomerge option that allows column to do the right thing with empty fields. Internally, column
uses the wcstok(wcs, delim, ptr)
function, which splits a wide character string into tokens delimited by the wide characters in the delim
argument.
wcstok
starts by skipping wide characters in delim
, before recognizing the token. The -n
option uses an algorythm that doesn't skip initial wide-characters in delim
.
Unfortunately, this isn't very portable: -n
is Debian-specific, and column
is not in POSIX, it's apparently a BSD thing.
add a comment |
Taking out the dots that you used for padding:
file1:
ETIAM
SED
MAECENAS
DONEC
SUSPENDISSE
file2:
Lorem
Proin
Nunc
Quisque
Aenean
Nam
Vivamus
Curabitur
Nullam
Try this:
$ ( echo ".TS"; echo "l l."; paste file1 file2; echo ".TE" ) | tbl | nroff | more
And you will get:
ETIAM Lorem
SED Proin
MAECENAS Nunc
DONEC Quisque
SUSPENDISSE Aenean
Nam
Vivamus
Curabitur
Nullam
This, like the other solutions usingpaste
will fail to print the proper output if there are any lines containing tabs. +1 for being different though
– don_crissti
Feb 15 '17 at 21:12
+1. Would you please explain how the solution works?
– Tulains Córdova
Feb 15 '17 at 22:45
add a comment |
An awk
solution that should be fairly portable, and should work for an arbitrary number of input files:
# 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
How do you use this on file1 and file2? I called the scriptpaste-awk
and triedpaste file1 file2|paste-awk
and I triedawk paste-awk file1 file2
but none worked.
– rubo77
Nov 30 '13 at 7:04
I getawk: Line:1: (FILENAME=file1 FNR=1) Fatal: Division by zero
– rubo77
Nov 30 '13 at 7:04
@rubo77:awk -f paste-awk file1 file2
should work, at least for GNU awk and mawk.
– ninjalj
Dec 2 '13 at 10:32
This works, although it is slightly different frompaste
there is less space between the two rows. And if the input file has not all rows same length, it will result in an align-right row
– rubo77
Dec 2 '13 at 14:14
@rubo77: the field separator can be set with-F\t
– ninjalj
Dec 2 '13 at 15:30
add a comment |
Your Answer
StackExchange.ready(function()
var channelOptions =
tags: "".split(" "),
id: "106"
;
initTagRenderer("".split(" "), "".split(" "), channelOptions);
StackExchange.using("externalEditor", function()
// Have to fire editor after snippets, if snippets enabled
if (StackExchange.settings.snippets.snippetsEnabled)
StackExchange.using("snippets", function()
createEditor();
);
else
createEditor();
);
function createEditor()
StackExchange.prepareEditor(
heartbeatType: 'answer',
autoActivateHeartbeat: false,
convertImagesToLinks: false,
noModals: true,
showLowRepImageUploadWarning: true,
reputationToPostImages: null,
bindNavPrevention: true,
postfix: "",
imageUploader:
brandingHtml: "Powered by u003ca class="icon-imgur-white" href="https://imgur.com/"u003eu003c/au003e",
contentPolicyHtml: "User contributions licensed under u003ca href="https://creativecommons.org/licenses/by-sa/3.0/"u003ecc by-sa 3.0 with attribution requiredu003c/au003e u003ca href="https://stackoverflow.com/legal/content-policy"u003e(content policy)u003c/au003e",
allowUrls: true
,
onDemand: true,
discardSelector: ".discard-answer"
,immediatelyShowMarkdownHelp:true
);
);
Sign up or log in
StackExchange.ready(function ()
StackExchange.helpers.onClickDraftSave('#login-link');
);
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
StackExchange.ready(
function ()
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2funix.stackexchange.com%2fquestions%2f98945%2fa-better-paste-command%23new-answer', 'question_page');
);
Post as a guest
Required, but never shown
6 Answers
6
active
oldest
votes
6 Answers
6
active
oldest
votes
active
oldest
votes
active
oldest
votes
Assuming you don't have any tab characters in your files,
paste file1 file2 | expand -t 13
with the arg to -t
suitably chosen to cover the desired max line width in file1.
OP has added a more flexible solution:
I did this so it works without the magic number 13:
paste file1 file2 | expand -t $(( $(wc -L <file1) + 2 ))
It's not easy to type but can be used in a script.
nice! I didn't know about expand before I read your answer :)
– TabeaKischka
Dec 7 '18 at 14:30
add a comment |
Assuming you don't have any tab characters in your files,
paste file1 file2 | expand -t 13
with the arg to -t
suitably chosen to cover the desired max line width in file1.
OP has added a more flexible solution:
I did this so it works without the magic number 13:
paste file1 file2 | expand -t $(( $(wc -L <file1) + 2 ))
It's not easy to type but can be used in a script.
nice! I didn't know about expand before I read your answer :)
– TabeaKischka
Dec 7 '18 at 14:30
add a comment |
Assuming you don't have any tab characters in your files,
paste file1 file2 | expand -t 13
with the arg to -t
suitably chosen to cover the desired max line width in file1.
OP has added a more flexible solution:
I did this so it works without the magic number 13:
paste file1 file2 | expand -t $(( $(wc -L <file1) + 2 ))
It's not easy to type but can be used in a script.
Assuming you don't have any tab characters in your files,
paste file1 file2 | expand -t 13
with the arg to -t
suitably chosen to cover the desired max line width in file1.
OP has added a more flexible solution:
I did this so it works without the magic number 13:
paste file1 file2 | expand -t $(( $(wc -L <file1) + 2 ))
It's not easy to type but can be used in a script.
edited Dec 7 '18 at 16:07
answered Nov 5 '13 at 15:02
Mark PlotnickMark Plotnick
18.7k24169
18.7k24169
nice! I didn't know about expand before I read your answer :)
– TabeaKischka
Dec 7 '18 at 14:30
add a comment |
nice! I didn't know about expand before I read your answer :)
– TabeaKischka
Dec 7 '18 at 14:30
nice! I didn't know about expand before I read your answer :)
– TabeaKischka
Dec 7 '18 at 14:30
nice! I didn't know about expand before I read your answer :)
– TabeaKischka
Dec 7 '18 at 14:30
add a comment |
I thought awk might do it nicely, so I googled "awk reading input from two files" and found an article on stackoverflow to use as a starting point.
First is the condensed version, then fully commented below that. This took a more than a few minutes to work out. I'd be glad of some refinements from smarter folks.
awk 'if(length($0)>max)max=length($0)
FNR==NRs1[FNR]=$0;nexts2[FNR]=$0
END format = "%-" max "st%-" max "sn";
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
And here is the fully documented version of the above.
# 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 "st%-" max "sn"
# 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]:""
1
+1 this is the only answer that does work with arbitrary input (i.e. with lines that may contain tabs). I don't think this could be significantly refined/improved.
– don_crissti
Feb 15 '17 at 21:21
add a comment |
I thought awk might do it nicely, so I googled "awk reading input from two files" and found an article on stackoverflow to use as a starting point.
First is the condensed version, then fully commented below that. This took a more than a few minutes to work out. I'd be glad of some refinements from smarter folks.
awk 'if(length($0)>max)max=length($0)
FNR==NRs1[FNR]=$0;nexts2[FNR]=$0
END format = "%-" max "st%-" max "sn";
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
And here is the fully documented version of the above.
# 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 "st%-" max "sn"
# 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]:""
1
+1 this is the only answer that does work with arbitrary input (i.e. with lines that may contain tabs). I don't think this could be significantly refined/improved.
– don_crissti
Feb 15 '17 at 21:21
add a comment |
I thought awk might do it nicely, so I googled "awk reading input from two files" and found an article on stackoverflow to use as a starting point.
First is the condensed version, then fully commented below that. This took a more than a few minutes to work out. I'd be glad of some refinements from smarter folks.
awk 'if(length($0)>max)max=length($0)
FNR==NRs1[FNR]=$0;nexts2[FNR]=$0
END format = "%-" max "st%-" max "sn";
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
And here is the fully documented version of the above.
# 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 "st%-" max "sn"
# 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]:""
I thought awk might do it nicely, so I googled "awk reading input from two files" and found an article on stackoverflow to use as a starting point.
First is the condensed version, then fully commented below that. This took a more than a few minutes to work out. I'd be glad of some refinements from smarter folks.
awk 'if(length($0)>max)max=length($0)
FNR==NRs1[FNR]=$0;nexts2[FNR]=$0
END format = "%-" max "st%-" max "sn";
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
And here is the fully documented version of the above.
# 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 "st%-" max "sn"
# 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]:""
edited May 23 '17 at 12:39
Community♦
1
1
answered Nov 6 '13 at 0:01
Mike DiehnMike Diehn
81356
81356
1
+1 this is the only answer that does work with arbitrary input (i.e. with lines that may contain tabs). I don't think this could be significantly refined/improved.
– don_crissti
Feb 15 '17 at 21:21
add a comment |
1
+1 this is the only answer that does work with arbitrary input (i.e. with lines that may contain tabs). I don't think this could be significantly refined/improved.
– don_crissti
Feb 15 '17 at 21:21
1
1
+1 this is the only answer that does work with arbitrary input (i.e. with lines that may contain tabs). I don't think this could be significantly refined/improved.
– don_crissti
Feb 15 '17 at 21:21
+1 this is the only answer that does work with arbitrary input (i.e. with lines that may contain tabs). I don't think this could be significantly refined/improved.
– don_crissti
Feb 15 '17 at 21:21
add a comment |
Not a very good solution but I was able to do it using
paste file1 file2 | sed 's/^TAB/&&/'
where TAB is replaced with the tab character.
What is the role of&&
in the sed command?
– coffeMug
Nov 5 '13 at 14:57
1
A single&
puts what is being searched for (a tab in this case). This command simply replaces the tab at the beginning with two tabs.
– unxnut
Nov 5 '13 at 15:59
I had to changeTAB
tot
to make this work in zsh on Ubuntu debian. And it does only work if file1 has less than 15 chars
– rubo77
Nov 30 '13 at 6:53
add a comment |
Not a very good solution but I was able to do it using
paste file1 file2 | sed 's/^TAB/&&/'
where TAB is replaced with the tab character.
What is the role of&&
in the sed command?
– coffeMug
Nov 5 '13 at 14:57
1
A single&
puts what is being searched for (a tab in this case). This command simply replaces the tab at the beginning with two tabs.
– unxnut
Nov 5 '13 at 15:59
I had to changeTAB
tot
to make this work in zsh on Ubuntu debian. And it does only work if file1 has less than 15 chars
– rubo77
Nov 30 '13 at 6:53
add a comment |
Not a very good solution but I was able to do it using
paste file1 file2 | sed 's/^TAB/&&/'
where TAB is replaced with the tab character.
Not a very good solution but I was able to do it using
paste file1 file2 | sed 's/^TAB/&&/'
where TAB is replaced with the tab character.
answered Nov 5 '13 at 14:21
unxnutunxnut
3,78721120
3,78721120
What is the role of&&
in the sed command?
– coffeMug
Nov 5 '13 at 14:57
1
A single&
puts what is being searched for (a tab in this case). This command simply replaces the tab at the beginning with two tabs.
– unxnut
Nov 5 '13 at 15:59
I had to changeTAB
tot
to make this work in zsh on Ubuntu debian. And it does only work if file1 has less than 15 chars
– rubo77
Nov 30 '13 at 6:53
add a comment |
What is the role of&&
in the sed command?
– coffeMug
Nov 5 '13 at 14:57
1
A single&
puts what is being searched for (a tab in this case). This command simply replaces the tab at the beginning with two tabs.
– unxnut
Nov 5 '13 at 15:59
I had to changeTAB
tot
to make this work in zsh on Ubuntu debian. And it does only work if file1 has less than 15 chars
– rubo77
Nov 30 '13 at 6:53
What is the role of
&&
in the sed command?– coffeMug
Nov 5 '13 at 14:57
What is the role of
&&
in the sed command?– coffeMug
Nov 5 '13 at 14:57
1
1
A single
&
puts what is being searched for (a tab in this case). This command simply replaces the tab at the beginning with two tabs.– unxnut
Nov 5 '13 at 15:59
A single
&
puts what is being searched for (a tab in this case). This command simply replaces the tab at the beginning with two tabs.– unxnut
Nov 5 '13 at 15:59
I had to change
TAB
to t
to make this work in zsh on Ubuntu debian. And it does only work if file1 has less than 15 chars– rubo77
Nov 30 '13 at 6:53
I had to change
TAB
to t
to make this work in zsh on Ubuntu debian. And it does only work if file1 has less than 15 chars– rubo77
Nov 30 '13 at 6:53
add a comment |
On Debian and derivatives, column
has a -n
nomerge option that allows column to do the right thing with empty fields. Internally, column
uses the wcstok(wcs, delim, ptr)
function, which splits a wide character string into tokens delimited by the wide characters in the delim
argument.
wcstok
starts by skipping wide characters in delim
, before recognizing the token. The -n
option uses an algorythm that doesn't skip initial wide-characters in delim
.
Unfortunately, this isn't very portable: -n
is Debian-specific, and column
is not in POSIX, it's apparently a BSD thing.
add a comment |
On Debian and derivatives, column
has a -n
nomerge option that allows column to do the right thing with empty fields. Internally, column
uses the wcstok(wcs, delim, ptr)
function, which splits a wide character string into tokens delimited by the wide characters in the delim
argument.
wcstok
starts by skipping wide characters in delim
, before recognizing the token. The -n
option uses an algorythm that doesn't skip initial wide-characters in delim
.
Unfortunately, this isn't very portable: -n
is Debian-specific, and column
is not in POSIX, it's apparently a BSD thing.
add a comment |
On Debian and derivatives, column
has a -n
nomerge option that allows column to do the right thing with empty fields. Internally, column
uses the wcstok(wcs, delim, ptr)
function, which splits a wide character string into tokens delimited by the wide characters in the delim
argument.
wcstok
starts by skipping wide characters in delim
, before recognizing the token. The -n
option uses an algorythm that doesn't skip initial wide-characters in delim
.
Unfortunately, this isn't very portable: -n
is Debian-specific, and column
is not in POSIX, it's apparently a BSD thing.
On Debian and derivatives, column
has a -n
nomerge option that allows column to do the right thing with empty fields. Internally, column
uses the wcstok(wcs, delim, ptr)
function, which splits a wide character string into tokens delimited by the wide characters in the delim
argument.
wcstok
starts by skipping wide characters in delim
, before recognizing the token. The -n
option uses an algorythm that doesn't skip initial wide-characters in delim
.
Unfortunately, this isn't very portable: -n
is Debian-specific, and column
is not in POSIX, it's apparently a BSD thing.
answered Nov 6 '13 at 17:06
ninjaljninjalj
1,2471110
1,2471110
add a comment |
add a comment |
Taking out the dots that you used for padding:
file1:
ETIAM
SED
MAECENAS
DONEC
SUSPENDISSE
file2:
Lorem
Proin
Nunc
Quisque
Aenean
Nam
Vivamus
Curabitur
Nullam
Try this:
$ ( echo ".TS"; echo "l l."; paste file1 file2; echo ".TE" ) | tbl | nroff | more
And you will get:
ETIAM Lorem
SED Proin
MAECENAS Nunc
DONEC Quisque
SUSPENDISSE Aenean
Nam
Vivamus
Curabitur
Nullam
This, like the other solutions usingpaste
will fail to print the proper output if there are any lines containing tabs. +1 for being different though
– don_crissti
Feb 15 '17 at 21:12
+1. Would you please explain how the solution works?
– Tulains Córdova
Feb 15 '17 at 22:45
add a comment |
Taking out the dots that you used for padding:
file1:
ETIAM
SED
MAECENAS
DONEC
SUSPENDISSE
file2:
Lorem
Proin
Nunc
Quisque
Aenean
Nam
Vivamus
Curabitur
Nullam
Try this:
$ ( echo ".TS"; echo "l l."; paste file1 file2; echo ".TE" ) | tbl | nroff | more
And you will get:
ETIAM Lorem
SED Proin
MAECENAS Nunc
DONEC Quisque
SUSPENDISSE Aenean
Nam
Vivamus
Curabitur
Nullam
This, like the other solutions usingpaste
will fail to print the proper output if there are any lines containing tabs. +1 for being different though
– don_crissti
Feb 15 '17 at 21:12
+1. Would you please explain how the solution works?
– Tulains Córdova
Feb 15 '17 at 22:45
add a comment |
Taking out the dots that you used for padding:
file1:
ETIAM
SED
MAECENAS
DONEC
SUSPENDISSE
file2:
Lorem
Proin
Nunc
Quisque
Aenean
Nam
Vivamus
Curabitur
Nullam
Try this:
$ ( echo ".TS"; echo "l l."; paste file1 file2; echo ".TE" ) | tbl | nroff | more
And you will get:
ETIAM Lorem
SED Proin
MAECENAS Nunc
DONEC Quisque
SUSPENDISSE Aenean
Nam
Vivamus
Curabitur
Nullam
Taking out the dots that you used for padding:
file1:
ETIAM
SED
MAECENAS
DONEC
SUSPENDISSE
file2:
Lorem
Proin
Nunc
Quisque
Aenean
Nam
Vivamus
Curabitur
Nullam
Try this:
$ ( echo ".TS"; echo "l l."; paste file1 file2; echo ".TE" ) | tbl | nroff | more
And you will get:
ETIAM Lorem
SED Proin
MAECENAS Nunc
DONEC Quisque
SUSPENDISSE Aenean
Nam
Vivamus
Curabitur
Nullam
edited Feb 15 '17 at 20:54
answered Feb 15 '17 at 20:47
Jeff TaylorJeff Taylor
1213
1213
This, like the other solutions usingpaste
will fail to print the proper output if there are any lines containing tabs. +1 for being different though
– don_crissti
Feb 15 '17 at 21:12
+1. Would you please explain how the solution works?
– Tulains Córdova
Feb 15 '17 at 22:45
add a comment |
This, like the other solutions usingpaste
will fail to print the proper output if there are any lines containing tabs. +1 for being different though
– don_crissti
Feb 15 '17 at 21:12
+1. Would you please explain how the solution works?
– Tulains Córdova
Feb 15 '17 at 22:45
This, like the other solutions using
paste
will fail to print the proper output if there are any lines containing tabs. +1 for being different though– don_crissti
Feb 15 '17 at 21:12
This, like the other solutions using
paste
will fail to print the proper output if there are any lines containing tabs. +1 for being different though– don_crissti
Feb 15 '17 at 21:12
+1. Would you please explain how the solution works?
– Tulains Córdova
Feb 15 '17 at 22:45
+1. Would you please explain how the solution works?
– Tulains Córdova
Feb 15 '17 at 22:45
add a comment |
An awk
solution that should be fairly portable, and should work for an arbitrary number of input files:
# 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
How do you use this on file1 and file2? I called the scriptpaste-awk
and triedpaste file1 file2|paste-awk
and I triedawk paste-awk file1 file2
but none worked.
– rubo77
Nov 30 '13 at 7:04
I getawk: Line:1: (FILENAME=file1 FNR=1) Fatal: Division by zero
– rubo77
Nov 30 '13 at 7:04
@rubo77:awk -f paste-awk file1 file2
should work, at least for GNU awk and mawk.
– ninjalj
Dec 2 '13 at 10:32
This works, although it is slightly different frompaste
there is less space between the two rows. And if the input file has not all rows same length, it will result in an align-right row
– rubo77
Dec 2 '13 at 14:14
@rubo77: the field separator can be set with-F\t
– ninjalj
Dec 2 '13 at 15:30
add a comment |
An awk
solution that should be fairly portable, and should work for an arbitrary number of input files:
# 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
How do you use this on file1 and file2? I called the scriptpaste-awk
and triedpaste file1 file2|paste-awk
and I triedawk paste-awk file1 file2
but none worked.
– rubo77
Nov 30 '13 at 7:04
I getawk: Line:1: (FILENAME=file1 FNR=1) Fatal: Division by zero
– rubo77
Nov 30 '13 at 7:04
@rubo77:awk -f paste-awk file1 file2
should work, at least for GNU awk and mawk.
– ninjalj
Dec 2 '13 at 10:32
This works, although it is slightly different frompaste
there is less space between the two rows. And if the input file has not all rows same length, it will result in an align-right row
– rubo77
Dec 2 '13 at 14:14
@rubo77: the field separator can be set with-F\t
– ninjalj
Dec 2 '13 at 15:30
add a comment |
An awk
solution that should be fairly portable, and should work for an arbitrary number of input files:
# 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
An awk
solution that should be fairly portable, and should work for an arbitrary number of input files:
# 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
edited Dec 2 '13 at 18:30
rubo77
7,9022573137
7,9022573137
answered Nov 6 '13 at 19:49
ninjaljninjalj
1,2471110
1,2471110
How do you use this on file1 and file2? I called the scriptpaste-awk
and triedpaste file1 file2|paste-awk
and I triedawk paste-awk file1 file2
but none worked.
– rubo77
Nov 30 '13 at 7:04
I getawk: Line:1: (FILENAME=file1 FNR=1) Fatal: Division by zero
– rubo77
Nov 30 '13 at 7:04
@rubo77:awk -f paste-awk file1 file2
should work, at least for GNU awk and mawk.
– ninjalj
Dec 2 '13 at 10:32
This works, although it is slightly different frompaste
there is less space between the two rows. And if the input file has not all rows same length, it will result in an align-right row
– rubo77
Dec 2 '13 at 14:14
@rubo77: the field separator can be set with-F\t
– ninjalj
Dec 2 '13 at 15:30
add a comment |
How do you use this on file1 and file2? I called the scriptpaste-awk
and triedpaste file1 file2|paste-awk
and I triedawk paste-awk file1 file2
but none worked.
– rubo77
Nov 30 '13 at 7:04
I getawk: Line:1: (FILENAME=file1 FNR=1) Fatal: Division by zero
– rubo77
Nov 30 '13 at 7:04
@rubo77:awk -f paste-awk file1 file2
should work, at least for GNU awk and mawk.
– ninjalj
Dec 2 '13 at 10:32
This works, although it is slightly different frompaste
there is less space between the two rows. And if the input file has not all rows same length, it will result in an align-right row
– rubo77
Dec 2 '13 at 14:14
@rubo77: the field separator can be set with-F\t
– ninjalj
Dec 2 '13 at 15:30
How do you use this on file1 and file2? I called the script
paste-awk
and tried paste file1 file2|paste-awk
and I tried awk paste-awk file1 file2
but none worked.– rubo77
Nov 30 '13 at 7:04
How do you use this on file1 and file2? I called the script
paste-awk
and tried paste file1 file2|paste-awk
and I tried awk paste-awk file1 file2
but none worked.– rubo77
Nov 30 '13 at 7:04
I get
awk: Line:1: (FILENAME=file1 FNR=1) Fatal: Division by zero
– rubo77
Nov 30 '13 at 7:04
I get
awk: Line:1: (FILENAME=file1 FNR=1) Fatal: Division by zero
– rubo77
Nov 30 '13 at 7:04
@rubo77:
awk -f paste-awk file1 file2
should work, at least for GNU awk and mawk.– ninjalj
Dec 2 '13 at 10:32
@rubo77:
awk -f paste-awk file1 file2
should work, at least for GNU awk and mawk.– ninjalj
Dec 2 '13 at 10:32
This works, although it is slightly different from
paste
there is less space between the two rows. And if the input file has not all rows same length, it will result in an align-right row– rubo77
Dec 2 '13 at 14:14
This works, although it is slightly different from
paste
there is less space between the two rows. And if the input file has not all rows same length, it will result in an align-right row– rubo77
Dec 2 '13 at 14:14
@rubo77: the field separator can be set with
-F\t
– ninjalj
Dec 2 '13 at 15:30
@rubo77: the field separator can be set with
-F\t
– ninjalj
Dec 2 '13 at 15:30
add a comment |
Thanks for contributing an answer to Unix & Linux Stack Exchange!
- Please be sure to answer the question. Provide details and share your research!
But avoid …
- Asking for help, clarification, or responding to other answers.
- Making statements based on opinion; back them up with references or personal experience.
To learn more, see our tips on writing great answers.
Sign up or log in
StackExchange.ready(function ()
StackExchange.helpers.onClickDraftSave('#login-link');
);
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
StackExchange.ready(
function ()
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2funix.stackexchange.com%2fquestions%2f98945%2fa-better-paste-command%23new-answer', 'question_page');
);
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function ()
StackExchange.helpers.onClickDraftSave('#login-link');
);
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function ()
StackExchange.helpers.onClickDraftSave('#login-link');
);
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function ()
StackExchange.helpers.onClickDraftSave('#login-link');
);
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
-columns, paste, text-processing
2
paste
is using tabs in front of the lines from second file. You may have to use a postprocessor to align the columns appropriately.– unxnut
Nov 5 '13 at 14:17
3
paste file1 file2 | column -tn
?– ninjalj
Nov 5 '13 at 14:18
does file1 always have fixed size columns?
– RSFalcon7
Nov 5 '13 at 14:18
@RSFalcon7 Yes, it does.
– Tulains Córdova
Nov 6 '13 at 0:42