ProgrammingThis forum is for all programming questions.
The question does not have to be directly related to Linux and any language is fair game.
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.
Maybe there are more concise and elegant solutions, but... here we go...
Code:
#!/bin/sh
#
mkdir /tmp/my_dir
awk '
!/row|^$/ {
file = $0
print > "/tmp/my_dir/" file
while ( getline line > 0 ) {
if ( line ~ /row/ )
print line > "/tmp/my_dir/" file
else
break
}
}' infile
for file in `echo /tmp/my_dir/*`
do
cat $file >> ./sorted_file
echo >> ./sorted_file
done
rm -r /tmp/my_dir
The first part uses awk to split the input file into multiple files, named after each subject. Since you didn't provide a real example, I had to do some strong assumptions:
each section (the subject and its rows) is always separated by a single blank line,
the rows contain a common pattern, that never appears in the subject,
the subject doesn't contain blank spaces, punctuation or any other special character.
The second part of the script just let the shell sort the file names through the filename expansion in the echo statement. The sorted file is built accordingly.
If you are on a Solaris machine, using getline into a variable in awk doesn't work. In this case, try nawk instead. Or gawk if available. As I said, not a great solution, but just an idea!
Thanks all for responding; appreciated very much. I used the input of colucix and created my own script. Although I tried to use msort-gui on my ubuntu (nasty/11.04) computer. I could not run it, but as written before I used the input of colucix.
The script is as follows:
Code:
#!/bin/sh
#
# script to sort a file based on a certain structure
#
# ----------------------------------[ VARIABLES ]-------------------------------------------------------------------------------------
FILE_IN="inputfile.txt" # input file name
CONFIG_DIR="/conf" # directory where the config files are
TEMP_DIR="/tmp" # temporary directory
#
# just to make sure ;)
[ ${TEMP_DIR} = */ ] && TEMP_DIR=`echo ${TEMP_DIR:0:-1}` # if exits remove last backslash of TEMP_DIR
if [ ${#CONFIG_DIR} -gt 1 ]; then # if length of CONFIG_DIR name is greater then 1
[ ${CONFIG_DIR} = */ ] && CONFIG_DIR=`echo ${CONFIG_DIR:0:-1}` # if exits remove last backslash of CONFIG_DIR
else
CONFIG_DIR=""
fi
TEMP_DIR=${TEMP_DIR}/my_dir
[ -d ${TEMP_DIR} ] && rm -r ${TEMP_DIR} > /dev/null # if exists: delete temporary directory
mkdir ${TEMP_DIR} # create temporary directory
[ ! -d ${TEMP_DIR} ] && echo "Could not create ${TEMP_DIR}, script aborted." && exit
clear
[ ! -f ${CONFIG_DIR}/${FILE_IN} ] && echo "${CONFIG_DIR}/${FILE_IN} not found, nothing to do." && exit # abort script if $CONFIG_DIR does not exist
FILE_OUT="_${FILE_IN}" # temporary output filename
echo -n "[1;33;40mReading, sorting and writing ${CONFIG_DIR}/${FILE_IN}...[0m" # screen output
[ ! -f ${CONFIG_DIR}/${FILE_IN}_OLD ] && mv ${CONFIG_DIR}/${FILE_IN} ${CONFIG_DIR}/${FILE_IN}_OLD # rename $FILE_IN to $FILE_IN_OLD
awk ' # read $FILE_IN and create temporary files
/\[.+\]/ {
gsub(/\[|\]/,"")
file = $0
print "[" $0 "]" > "/tmp/my_dir/" file
while ( getline line > 0 ) {
if ( line !~ /^$/ )
print line > "/tmp/my_dir/" file
else
break
}
}' ${CONFIG_DIR}/${FILE_IN}
[ -f ${CONFIG_DIR}/${FILE_OUT} ] && rm -f ${CONFIG_DIR}/${FILE_OUT} > /dev/null # if $FILE_OUT exists: delete it
touch ${CONFIG_DIR}/${FILE_OUT} # create $FILE_OUT
for file in `echo ${TEMP_DIR}/*` # read and combine files in temporary directory to $FILE_OUT
do
cat $file >> ${CONFIG_DIR}/${FILE_OUT} # read file and write to $FILE_OUT
echo >> ${CONFIG_DIR}/${FILE_OUT} # write empty line to $FILE_OUT
done
rm -r /tmp/my_dir > /dev/null # remove temporary directory
echo; echo "[1;36;40mSorted file created: ${CONFIG_DIR}/${FILE_OUT}[0m" # screen output
echo
I am an AWK-rookie so unfortunately I do not understand everything of what is written in the AWK-part of the script. It is easy to copy & paste source code of someone else but I think it is much better if you understand that source code.
In the AWK-part is written (twice): "/tmp/my_dir/". I tried to change it to the variable ${TEMP_DIR} but that resulted in an error. Question is: if and how I can replace "/tmp/my_dir/" by the variable ${TEMP_DIR}.
Notice the awk code is written inside single quotes: this prevents the parameter expansion from the shell. The most straightforward method to pass an external variable to awk (provided your awk version supports it) is the -v option. Example:
Code:
awk -v dir=${TEMP_DIR} '
/\[.+\]/ {
gsub(/\[|\]/,"")
file = $0
print "[" $0 "]" > dir "/" file
while ( getline line > 0 ) {
if ( line !~ /^$/ )
print line > dir "/" file
else
break
}
}' ${CONFIG_DIR}/${FILE_IN}
awfull, thanks. The awk I use does recognize the -v option, so it worked.
I will view the link you posted to know more about awk. AFAI now recognized a lot is possible with awk, but a long way to go to understand it.
Have to find out how to sort data in another file:
[banana]
color=
length=
price=
LinuxQuestions.org is looking for people interested in writing
Editorials, Articles, Reviews, and more. If you'd like to contribute
content, let us know.