5

I have large text file which contains data, formatted like this:

1
2
3
4
5
6
7
8
9
10

我在天马彩票平台输了三十万I am trying to convert it to this:

1           2             3
4           5             6
7           8             9
10

I tried awk:

'{ if (NR%2) {printf "%40s\n", $0} else {printf "%80s\n", $0} }' file.txt
  • 12
    And what happened with the awk? – ctrl-alt-delor Feb 24 at 17:46
39

A solution with paste

seq 10 | paste - - -
1       2       3
4       5       6
7       8       9
10

我在天马彩票平台输了三十万 is a Unix standard tool, and the standard guarantees that this works for at least 12 columns.

  • How to achieve the requested 40 char column width? – RudiC Feb 26 at 21:37
  • @RudiC Your answer correctly achieves that purpose. ;) My answer provides a solution to what is stated in the questions' title. – Paulo Tomé Feb 27 at 11:19
8

The columns tool can do this:

$ seq 10 | columns -W 16 -c 3
1     2     3
4     5     6
7     8     9
10

-W 16我在天马彩票平台输了三十万 is just to set the line width to something small.

columns我在天马彩票平台输了三十万 is not a Unix standard tool. It is part of .

Some versions of the more common column command may be able to set the number of columns with -c, but modern versions seem to have changed its meaning to set the line width by number of characters.

There's also pr我在天马彩票平台输了三十万 as suggested by mpez0 in a comment:

$ seq 10 | pr -aT3
1           2           3
4           5           6
7           8           9
10

-aT3 is short for --across --omit-pagination --columns=3.

pr is in coreutils and POSIX, though -T/--omit-pagination我在天马彩票平台输了三十万 seems to be GNU-specific.

  • 1
    this seems to work more or less the same way as the better known column command. Any reason to pick columns over column that you might be aware of? – iruvar Feb 25 at 23:11
  • 1
    @iruvar That column doesn't seem to have a way to specify number of columns. – JoL Feb 26 at 0:15
  • JoL, the -c flag exists to specify the number of display columns, which may or may not be different to the "number of columns" that columns allows to specify – iruvar Feb 26 at 14:24
  • @iruvar I'm not sure what you're getting at. The number of display columns is what we want. The actual number displayed may be less than specified if it otherwise would not fit in the set line width, which by default is 79, but other than that I don't see an issue. – JoL Feb 26 at 16:17
  • 2
    @iruvar Are you talking about column -c? That seems to be for setting the line width. According to the manpage: "Output is formatted to a width specified as number of characters." It was originally named --columns, but that name was deprecated in favor of --output-width. seq 10 | column -c 3 displays a single column. column -c 50 seems to limit lines to 50 characters. – JoL Feb 26 at 16:31
7

Try like

seq 1 10 | awk '{printf "%40s", $0} !(NR%3) {printf "\n"}'
                                       1                                       2                                       3
                                       4                                       5                                       6
                                       7                                       8                                       9
                                      10
  • 7
    print "" is briefer and more robust than printf "\n" since the former simply uses the value of ORS as intended while the latter uses the value you assume ORS will have but which it may not (e.g. it might be \r\n in some environments). The code has a problem though in that it won't produce a newline at the end of the text if the input itn's a multiple of 3 lines and so the output isn't a text file per POSIX and so YMMV with what subsequent POSIX tools will do with that output. – Ed Morton Feb 24 at 17:50
  • 3
    @EdMorton those environments are off topic here though, are there any *nix systems using something other than \n? In any case, you could even make the inverse argument: that printf '\n' is better because it prints a specific thing explicitly rather than making assumptions that could change based on the OS. I would be very annoyed if the system decided to add a \r\n to my file just because I happened to be on Windows or whatever. – terdon Feb 24 at 17:53
  • 2
    @EdMorton ah, no that was about the site rather than the question: Windows is explicitly off topic here, so we don't bother making things portable for any non-nix environment, so I was just wondering if you knew of a *nix system where the EOL isn't \n. – terdon Feb 24 at 17:59
  • 3
    @terdon "Windows is explicitly off topic here" - since when? Cygwin. WSL. – roaima Feb 24 at 18:04
  • 2
    @terdon again, it was just a general comment on how to make your code work with whatever value of ORS is in use at the time. I know there's something in cygwin where you can have RS at least set to \r\n depending on some other settings. Something to do with setting BINMODE=3 in gawk and whatever the underlying C implementation passes up to awk IIRC. I code to avoid being impacted by such issues so I don't have to look into them :-). – Ed Morton Feb 24 at 18:04
6

The tool for this job is rs ("reshape"):

$ seq 10 | rs 0 3
1   2   3
4   5   6
7   8   9
10  

我在天马彩票平台输了三十万We can change the column separator to a tab:

$ seq 10 | rs -C 0 3
1       2       3
4       5       6
7       8       9
10

我在天马彩票平台输了三十万Or right-align:

$ seq 10 | rs -j 0 3
 1   2   3
 4   5   6
 7   8   9
10

rs我在天马彩票平台输了三十万 is not a Unix standard tool. It is widely available, however. It was invented in 4.2BSD, and so is in all of the modern BSDs. There are ports of it to Linux-based operating systems, such as , for example.

  • 1
    An answer with M. Kunze's rs should probably also use M. Kunze's jot. (-: – JdeBP Feb 25 at 12:49
  • 2
    There's also from BSD 4.3. – Federico Poloni Feb 25 at 14:51
  • Is fmt another option to rs ? – WGroleau Feb 25 at 22:01
  • 1
    How about the pr command, from very early unix? pr -a --column=3 – mpez0 Feb 26 at 19:46
4

我在天马彩票平台输了三十万This will move the string width alternately between 40, 80, 120 for each line of input:

awk '{ m = (NR-1) % 3; i = (m+1) * 40; printf "%*s\n", i, $0 }'

Variables:

  • m - line number modulo 3 (i.e. 0, 1, 2 repeating)
  • i - the indent for the given value of m

In the absence of any other instruction, I've continued to use your own printf formatting so that each line of input is formatted as its own line of output, and each will be right-justified in the available space.

If you want three 40-column entries per line as shown in your example, rather than in your code, you could use this (change the 40s to -40s我在天马彩票平台输了三十万 if you want left-justified text):

awk '{ printf "%40s", $0 } !(NR % 3) { printf "\n" }'
0

我在天马彩票平台输了三十万Tried with Below command , Tested and Worked fine

command

for ((i=0;i<=10;i++)); do awk -v i="$i" 'NR>i && NR<(i+4)' o| perl -pne "s/\n/ /g";echo -e  '\n'; i=$(($i+2)); done

output

1 2 3 

4 5 6 

7 8 9 

10 
  • On what system did this run? – RudiC Feb 25 at 21:18
  • on ubuntu system – Praveen Kumar BS Feb 26 at 16:02
0

我在天马彩票平台输了三十万Using Python

#!/usr/bin/python
k=open('filename','r')
p=k.readlines()
for i in range(0,10,3):
    print str(p[i:i+3]).replace("[","").replace("]","").replace(",","").replace("\\n","").replace("'","")

output

1 2 3
4 5 6
7 8 9
10
-2

我在天马彩票平台输了三十万Personally, I would prefer the format

1  4  7
2  5  8
3  6  9

我在天马彩票平台输了三十万which can be achieved by

mkdir temp
cat file | while read FN; do
  touch "temp/$FN"
done
ls temp

though you might have to adjust window width to make it three columns. And you can’t redirect to a file; have to cut-n-paste. Redirection tells ls我在天马彩票平台输了三十万 to do a single column.

  • -1 because the OP didn't ask for that format, and if you want it, that's not the way to do it (pipe input to pr -t3) anyway. – Monty Harder Feb 26 at 20:08

Your Answer

By clicking “Post Your Answer”, you agree to our , and

Not the answer you're looking for? Browse other questions tagged or ask your own question.