1

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

3
$ 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 Commented May 30, 2020 at 16:02
  • @StalinVigneshKumar I don't see this requirement in the question. Commented 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". Commented May 30, 2020 at 16:06
  • @Kusalananda : Never mind, any ways it can be done in your answer Commented 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. Commented May 30, 2020 at 16:09
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? Commented May 30, 2020 at 14:14
  • 2
    @Ashar If you have further requirements or restrictions, then these should be part of the question. Commented 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 :) Commented May 30, 2020 at 17:02
1

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

You must log in to answer this question.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.