How to convert 1 column into several rows in Linux?
Linux - SoftwareThis forum is for Software issues.
Having a problem installing a new program? Want to know which application is best for the job? Post your question in this forum.
Notices
Welcome to LinuxQuestions.org, a friendly and active Linux Community.
You are currently viewing LQ as a guest. By joining our community you will have the ability to post topics, receive our newsletter, use the advanced search, subscribe to threads and access many other special features. Registration is quick, simple and absolutely free. Join our community today!
Note that registered members see fewer ads, and ContentLink is completely disabled once you log in.
If you have any problems with the registration process or your account login, please contact us. If you need to reset your password, click here.
Having a problem logging in? Please visit this page to clear all LQ-related cookies.
Get a virtual cloud desktop with the Linux distro that you want in less than five minutes with Shells! With over 10 pre-installed distros to choose from, the worry-free installation life is here! Whether you are a digital nomad or just looking for flexibility, Shells can put your Linux machine on the device that you want to use.
Exclusive for LQ members, get up to 45% off per month. Click here for more info.
How to convert 1 column into several rows in Linux?
Suppose I have an ASCII file (=data.txt) that only contains 1 column :
#cat data.txt
item10
item11
item12
item20
item21
item22
item30
item31
item32
...
I am looking for a script that creates rows for each 3 elements in the column.
I know there are possibilities to convert the column entirely in 1 row (see this forum) but I do not see how I can convert into multiple rows, based on a fixed number of elements of the column.
This cant be that hard!! read a line from the file print is print a comma read another line print it print a comma read another line print it print a newline and so on ............
Here is almost what you want (it is a BASH script)
Save this. make it executable (using chmod)
This came from a script that acts on mutilple file in a dir and I wasn't sure how to strip that part away so I didn't.
It presumes that the input file is foo.dat and the output file is foo.new
I ran it and it works for me
Good Luck
Ken
#!/bin/sh
#doit4.sh
# effort at reading a column of items and outputting it as
# item1, item2, item3
# item 4, item 5,item 6 etc
for file in `ls foo.dat` ; do
exec < $file
while read line
do
temp1=$line
awk 'BEGIN { FS="\n"; ORS="," } { print $0 }' test | sed 's/\([a-zA-Z0-9]*,[a-zA-Z0-9]*,[a-zA-Z0-9]*\),/\1\n/g'
Only works if itemXX is made up out of lower case and/or upper case and/or digits. i.e. item_01 would fail......
The regular expression could be written shorter and better, but I leave that to somebody else
DarkstarNL's suggestion would allow you to make the code 'a bit' more readable and you also don't have the limitation that the above one-liner has (at the moment).
#!/bin/sh
n=0
for i in `cat ${1}`
do STR=${STR},${i}
let n=${n}+1
if [ "$n" -eq "3" ] ;
then echo ${STR} | sed 's/^,//g'
STR=""
n=0
fi
done
echo ${STR} | sed 's/^,//g'
Most of what I do here is just read and ask questions. It's rare that I am able to help anyone, and tonight I seem to have been able to help in 2 threads.
On another note, I got myself several wonderful linux books tonight. Well, 2 directly linux. I got "Linux Complete", "Linux Security Cookbook", and "Security+ For Dummies." This could be useful.
What if I desire to skip the first few lines before ordering the column vector into multiple rows? Can this be added to Matir's script? Also, I'd like to prevent any carriage returns in the output.
Maybe put a couple or three of these dummy line reads in before you start processing
temp=$line
not sure how to have no carriage returns but if you don't something, you'll get only 1 run-on line of output and you probably don't want that.
I ended up using a recursive sed '1d' in a shell script. Like this:
#!/bin/bash
COUNTER=0
sed '1d' 94Mo.Spe > temp_$COUNTER.txt
while [ $COUNTER != 11 ]
do
sed '1d' temp_$COUNTER.txt > temp_mid.txt
let COUNTER=COUNTER+1
cp temp_mid.txt temp_$COUNTER.txt
done
cp temp_$COUNTER.txt 94Mo_mod.txt
rm temp*.txt
This removed the header lines. Then, I opened the _mod.txt file in xemacs and used replace-string with CTRL-Q CTRL-M to remove the carriage returns. I then used the code from Matir below to rearrange the column into multiple rows. I modified it, so there were no commas, but instead a space in between:
#!/bin/sh
n=0
for i in `cat ${1}`
do STR=${STR}${i}" "
let n=${n}+1
if [ "$n" -eq "8" ] ;
then echo ${STR}
STR=""
n=0
fi
done
echo ${STR}
LinuxQuestions.org is looking for people interested in writing
Editorials, Articles, Reviews, and more. If you'd like to contribute
content, let us know.