0

I have a file test.txt which has huge entry a sample of which is below.

Afghanistan
Albania
Algeria
Andorra
Angola
Antigua and Barbuda
Argentina
Armenia
Australia
Austria
Azerbaijan
The Bahamas
Bahrain
Bangladesh
Barbados
Belarus
Belgium
Belize
Benin
Bhutan
Bolivia
Bosnia and Herzegovina
Botswana
Brazil
Brunei
Bulgaria
Burkina Faso
Burundi
Cabo Verde
Cambodia
Cameroon
Canada
Central African Republic
Chad
Chile
China
Colombia
Comoros

I can use cat test.txt | tr '\n' ',' to convert the new line into a comma-separated list.

However, I want the command separate list as a group of 6 each like below.

Afghanistan,Albania,Algeria,Andorra,Angola,Antigua and Barbuda
Argentina,Armenia,Australia,Austria,Azerbaijan,The Bahamas
Bahrain,Bangladesh,Barbados,Belarus,Belgium,Belize
and so on ...

How could I do this in Centos bash shell?

4 Answers 4

2
mapfile -t data < test.txt;
printf '%s,%s,%s,%s,%s,%s\n' "${data[@]}";

if offset is bigger and need a feasible solution use awk , else if you want pure shell you may need some looping !

f () { 
    offset=$1;
    infile="$2";
    mapfile -t data < "$infile";
    while ((${#data[@]}));do
        line="$(printf '%s,' "${data[@]:0:offset}")";
        data=("${data[@]:offset}");
        echo "${line%,*}";
    done
}
f 5 test.txt
2
  • Thank you for the answer but this solution may not be feasible in case I wish to have a group of 45 rows each. Could you provide a different solution?
    – Ashar
    May 30, 2020 at 14:14
  • 2
    @Ashar If you have further requirements or restrictions, then these should be part of the question.
    – Kusalananda
    May 30, 2020 at 16:14
2

For an arbitrary number of columns:

awk -v col=6 '{printf "%s%s", (NR>1) ? (NR-1) % col ? "," : RS : "", $0}
              END{if (NR) print ""}' < your-file

With pr (assuming the input like in your sample doesn't contain one of the special sequences recognised by some pr implementations; with the GNU one (as found on CEntOS), that includes at least the form-feed character):

pr -t -a -s, -6 < your-file

With GNU pr, you'll find you can't get more than 36 columns (half of 72, the default page width), unless you also use -w (or non-standard -W), but then you get some truncation / padding. You can work around that with -J (also a GNU extension), but who knows what other side effect that entails.

For 45 columns with GNU pr:

pr -Jtas, -w90 -45

(YMMV with other pr implementations, I find the pr command to be quite a jolly mess).

1
  • dear Stephane i always learn new skills from your answers :)
    – Yunus
    May 30, 2020 at 17:02
1
$ paste -d, - - - - - - <file
Afghanistan,Albania,Algeria,Andorra,Angola,Antigua and Barbuda
Argentina,Armenia,Australia,Austria,Azerbaijan,The Bahamas
Bahrain,Bangladesh,Barbados,Belarus,Belgium,Belize
Benin,Bhutan,Bolivia,Bosnia and Herzegovina,Botswana,Brazil
Brunei,Bulgaria,Burkina Faso,Burundi,Cabo Verde,Cambodia
Cameroon,Canada,Central African Republic,Chad,Chile,China
Colombia,Comoros,,,,

The paste command is here used to create output that is comma-delimited in six columns.

There is not enough data in the sample to fill the last few columns on the last line, so these are empty. If you want to delete these, then pipe the result through sed '$s/,*$//' which deletes all trailing commas on the last line:

$ paste -d, - - - - - - <file | sed '$s/,*$//'
Afghanistan,Albania,Algeria,Andorra,Angola,Antigua and Barbuda
Argentina,Armenia,Australia,Austria,Azerbaijan,The Bahamas
Bahrain,Bangladesh,Barbados,Belarus,Belgium,Belize
Benin,Bhutan,Bolivia,Bosnia and Herzegovina,Botswana,Brazil
Brunei,Bulgaria,Burkina Faso,Burundi,Cabo Verde,Cambodia
Cameroon,Canada,Central African Republic,Chad,Chile,China
Colombia,Comoros
5
  • it can be feasible paste -d, $(printf ' -%.0s' $(seq 6)) <file
    – Yunus
    May 30, 2020 at 16:02
  • @StalinVigneshKumar I don't see this requirement in the question.
    – Kusalananda
    May 30, 2020 at 16:04
  • @StalinVigneshKumar That does not count. Answers should answer the question as stated. Also, it's unclear what they mean by "45 rows each".
    – Kusalananda
    May 30, 2020 at 16:06
  • @Kusalananda : Never mind, any ways it can be done in your answer May 30, 2020 at 16:08
  • @StalinVigneshKumar Well, they could also mean they want to group the output into groups of 45 rows each, which is literally what they say. It's unclear and unimportant as it's not part of the requirements in the question.
    – Kusalananda
    May 30, 2020 at 16:09
0

awk can be used:

$ awk 'BEGIN{i=1;} { a[i]=a[i]","$0;if(NR%6==0){sub(",","",a[i]);print a[i];i++;} } END {if(a[i]){sub(",","",a[i]);print a[i]}}' file
Afghanistan,Albania,Algeria,Andorra,Angola,Antigua and Barbuda
Argentina,Armenia,Australia,Austria,Azerbaijan,The Bahamas
Bahrain,Bangladesh,Barbados,Belarus,Belgium,Belize
Benin,Bhutan,Bolivia,Bosnia and Herzegovina,Botswana,Brazil
Brunei,Bulgaria,Burkina Faso,Burundi,Cabo Verde,Cambodia
Cameroon,Canada,Central African Republic,Chad,Chile,China
Colombia,Comoros

OR Using perl one-liner :

perl -a -F'\n' -00 -ne ' map { (($_ + 1)%6 == 0) ? print $F[$_]."\n" : print $F[$_].",";  } ( 0 .. @F-1); print "\n" if eof' file
0

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

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