How do I format a file in 4 columns? - bash

cat file
01 02 03 04 05 06 07 08 09 10 11 12 13 14 15 16
I tried with
column -c 4 file
to get an output with 4 columns, but it didn't work - I just get the same as the input.
Do I misunderstand the column man-page?
A second question: what format should the argument to the -s flag have?

Give this a try:
fold -w 12 file
The number 12 is the number of data columns * the number of characters in a column (two digits + one space). The -w option is for designating a screen width in terms of character columns.
The column command won't work for this because it's intended to format newspaper-style columns.
This comes close to working the way you want:
sed 's/ /\n/g' file | column -xc 35
The "35" is somewhat arbitrary, but any value from 32 to 39 will work in this case. It's related to the width of the fields (2 characters which is less than the width of a tab stop), the number of fields desired per line and the width of tab stops (8 characters). So, basically, 8 * 4 is 32.
Here's a demonstration of the -s option (which is used with -t):
$ echo -e "a;b|c\naaaaa;bbbbb|ccccc"|column -t -s ';|'
a b c
aaaaa bbbbb ccccc
Without using column, the output looks like:
$ echo -e "a;b|c\naaaaa;bbbbb|ccccc"
a;b|c
aaaaa;bbbbb|ccccc

Let's guess you want:
01 02 03 04
05 06 07 08
09 10 11 12
13 14 15 16
In this case:
$ xargs -n4 < file

Related

Trying to get certain numbers and put them each on their own line

all the numbers inside the le that could be days in a month|
1-31. Assume that numbers 1-9 may or may not be preceded by a 0. The one or two digits of the numbers must be sandwiched by non-numeric characters. Print each matching number on its
own line.
So basically I read all the numbers 1-31 or 01-31 and output them on their own line.
What I know is that
I can use a split to maybe split this up and that would be good and I also know i could use something similar to ([1-9]|0[0-9]|1[1-9]|2[0-9]|3[0-1]) to find the numbers, but after that I'm stumped and could use some help.
Edit: to answer some questions this is in ruby and some test input / output here to help
Input-
1
10
12
18 19 20
21 22 ----asdfadsf 23t24####25,26,27,
28!
29.
30
31
32
33
01 02 03x04x05x06x07x08x09
001
002
1x1a
35
-87 76 101 10057
-13 -1.5
Output- 1
10
12
18
19
20
21
22
23
24
25
26
27
28
29
30
31
01
02
03
04
05
06
07
08
09
1
1
13
1
5
(each one of those on it's own line, but I didn't want to make it too long) I also removed a few to make it a smaller file so there is a chance i missed removing a number in the output, but I think I got them all.
This'll do it for you assuming your numbers are a single string x
x.split(/\D+/).select {|n| n.to_i >= 0 && n.to_i < 32 && n.length < 3}.join("\n")
If they are in a file, you can easily convert them to a string using IO::read(path)
x = IO.read(path)
x.split(/\D+/).select {|n| n.to_i >= 0 && n.to_i < 32 && n.length < 3}.join("\n")

Remove leading zero from BASH array variables

I am trying to remove leading zeroes from a BASH array... I have an array like:
echo "${DATES[#]}"
returns
01 02 02 03 04 07 08 09 10 11 13 14 15 16 17 18 20 21 22 23
I'd like to remove the leading zeroes from the dates and store back into array or another array, so i can iterate in another step... Any suggestions?
I tried this,
for i in "${!DATES[#]}"
do
DATESLZ["$i"]=(echo "{DATES["$i"]}"| sed 's/0*//' )
done
but failed (sorry, i'm an old Java programmer who was tasked to do some BASH scripts)
Use parameter expansion:
DATES=( ${DATES[#]#0} )
With bash arithmetic, you can avoid the octal woes by specifying your numbers are base-10:
day=08
((day++)) # bash: ((: 08: value too great for base (error token is "08")
((day = 10#$day + 1))
echo $day # 9
printf "%02d\n" $day # 09
You can use bash parameter expansion (see http://www.gnu.org/software/bash/manual/html_node/Shell-Parameter-Expansion.html) like this:
echo ${DATESLZ[#]#0}
If: ${onedate%%[!0]*} will select all 0's in front of the string $onedate.
we could remove those zeros by doing this (it is portable):
echo "${onedate#"${onedate%%[!0]*}"}"
For your case (only bash):
#!/bin/bash
dates=( 01 02 02 08 10 18 20 21 0008 00101 )
for onedate in "${dates[#]}"; do
echo -ne "${onedate}\t"
echo "${onedate#"${onedate%%[!0]*}"}"
done
Will print:
$ script.sh
01 1
02 2
02 2
08 8
10 10
18 18
20 20
21 21
0008 8
00101 101

Range with leading zero in bash

How to add leading zero to bash range?
For example, I need cycle 01,02,03,..,29,30
How can I implement this using bash?
In recent versions of bash you can do:
echo {01..30}
Output:
01 02 03 04 05 06 07 08 09 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30
Or if it should be comma separated:
echo {01..30} | tr ' ' ','
Which can also be accomplished with parameter expansion:
a=$(echo {01..30})
echo ${a// /,}
Output:
01,02,03,04,05,06,07,08,09,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30
another seq trick will work:
seq -w 30
if you check the man page, you will see the -w option is exactly for your requirement:
-w, --equal-width
equalize width by padding with leading zeroes
You can use seq's format option:
seq -f "%02g" 30
A "pure bash" way would be something like this:
echo {0..2}{0..9}
This will give you the following:
00 01 02 03 04 05 06 07 08 09 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29
Removing the first 00 and adding the last 30 is not too hard!
This works:
printf " %02d" $(seq 1 30)

unix cal command special character

When I try "cal | tail -6" in my unix machine, I get -
1 2 3
4 5 6 7 8 9 10
11 12 13 14 15 16 17
18 19 20 21 22 23 24
25 26 27 28 29 30
but when I try "cal | tail -6 | awk '{print $7}'", I get -
10
17
24
where is 3 going ? My requirement is basically all weekdays i.e column 2,3,4,5 & 6.
But I'm getting wrong output because of the strange behavior of "cal"
There are only 3 whitespace delimited columns in your first row. cal is working exactly as corrected, you are not understanding how awk works. As far as awk is concerned there is no 7th column in your first row as it yields attention to whitespace delimited columns, not fixed width columns.
A quick google search reveals you can use
BEGIN { FIELDWIDTHS = "3 3 3 3 3 3 3" }
In your awk script.
Since all of your columns in each row are three characters wide, you could use this to extract the days you wish for. For example, if you wanted only the 7th day in a column, you could do the following:
cal | sed 's/^\(.\{18\}\).*$/\1/'
This command would remove the first 18 characters in the line, which are the entries for the first 6 days of the week.
To extract a particular day, such as the fourth day, you could do this:
cal | sed 's/^.\{9\}\(.\{3\}\).*$/\1/'
To remove the first day of the week and the last day, you could do this:
cal | sed -e 's/^.\{3\}//' -e 's/^\(.\{15\}\).\{3\}$/\1/'
May be a row-wise extraction will do the trick. Try ncal. For example:
$ ncal
November 2012
Mo 5 12 19 26
Tu 6 13 20 27
We 7 14 21 28
Th 1 8 15 22 29
Fr 2 9 16 23 30
Sa 3 10 17 24
Su 4 11 18 25
or fill the absent dates with place holder (with '-' for example):
kent$ cal -s|tail -6|awk 'NR==1&&NF<7{gsub(/^ */,"");for(i=1;i<=(7-NF);i++) x=" - "x;$0=x" "$0;}1'
- - - - 1 2 3
4 5 6 7 8 9 10
11 12 13 14 15 16 17
18 19 20 21 22 23 24
25 26 27 28 29 30
then you could get the column, replace '-' with " " if needed. e.g. for $7:
kent$ cal -s|tail -6|awk 'NR==1&&NF<7{gsub(/^ */,"");for(i=1;i<=(7-NF);i++) x=" - "x;$0=x" "$0;}{print $7}'
3
10
17
24
Note that todays date is highlighted unless you turn it off (-h). Use cut to extract the wanted columns:
cal -h | cut -c19-20
Output:
Sa
3
10
17
24

Limit keywords for day in a Google Analytics API request

I'd like to know if there's a way to get the top 5 keywords by grouping them by days of the current month.
I'd like to receive a dataset like the following as result.
Supposing today is 4 of December i want to retrieve data for days from 1 to 4 of December, limiting the number of keywords for day to 5:
Day Keyword Visits
----------------------
01 keyword1 703
01 keyword2 688
01 keyword3 115
02 keyword1 109
02 keyword2 66
02 keyword3 53
02 keyword4 40
02 keyword5 23
03 keyword1 23
03 keyword2 19
03 keyword3 17
04 keyword1 14
04 keyword2 14
What i've currently done is setting the following parameters:
(you can test it here if you have a ganalytics account: http://code.google.com/intl/it-IT/apis/analytics/docs/gdata/gdataExplorer.html)
Dimensions: ga:day,ga:keyword
Metrics: ga:visits
Filters: ga:medium==organic;ga:keyword!=(not provided)
Sort: ga:day,-ga:visits,ga:keyword
Now i just need a method to limit the number of keywords for day (if possible).

Resources