Home
Man
Search
Today's Posts
Register

BSD, Linux, and UNIX shell scripting — Post awk, bash, csh, ksh, perl, php, python, sed, sh, shell scripts, and other shell scripting languages questions here.

Bash - re-ordering list of parameters

Tags
shell scripts

Login to Reply

 
Thread Tools Search this Thread
# 1  
Old 06-13-2018
Bash - re-ordering list of parameters

Hello.

I have a script that writes parameters in alphabetic order.
But I have a parameter which have 3 lines. There is no continuation character ( '\' ). Each of the three lines finish with 'cr'. But line 2 and 3 of the concerning parameter start with a tab char (but should be one or more space).
Code:
.............
.............
.............
debugger_command =
     PATH=/bin:/usr/bin:/usr/local/bin:/usr/X11R6/bin
     ddd $daemon_directory/$process_name $process_id & sleep 5
.............
.............
.............

When my script finished, I got this :
Code:
content_filter =
daemon_directory = /usr/lib/postfix
data_directory = /var/lib/postfix
     ddd $daemon_directory/$process_name $process_id & sleep 5
debugger_command =
debug_peer_level = 2
default_transport = error:outside mail is not deliverable
defer_transports =
.............
.............
.............
.............
     PATH=/bin:/usr/bin:/usr/local/bin:/usr/X11R6/bin
.............
.............

The position of the 3 red lines are arbitrary.

Now I would like now to re-read the result file and modify it to obtain this :
Code:
content_filter =
daemon_directory = /usr/lib/postfix
data_directory = /var/lib/postfix
debugger_command =
     ddd $daemon_directory/$process_name $process_id & sleep 5
     PATH=/bin:/usr/bin:/usr/local/bin:/usr/X11R6/bin
debug_peer_level = 2
default_transport = error:outside mail is not deliverable
defer_transports =
.............
 .............
.............

Any help is welcome.
# 2  
Old 06-13-2018
Post your script.
# 3  
Old 06-15-2018
Is it about sorting of arguments that are given to a script or a script function?
The sorting of arguments requires an explicit sorting, either with an external sort command or with a sort function.
A newline is an obstacle for the external sort command, unless sort understands -t $'\0' or similar tricks.
A shell function can do it, as shown by the following sample:
Code:
#!/bin/bash
# function from https://stackoverflow.com/questions/7442417/how-to-sort-an-array-in-bash
qsort() {
   local pivot i smaller=() larger=()
   qsort_ret=()
   (($#==0)) && return 0
   pivot=$1
   shift
   for i; do
      if [[ $i < $pivot ]]; then
         smaller+=( "$i" )
      else
         larger+=( "$i" )
      fi
   done
   qsort "${smaller[@]}"
   smaller=( "${qsort_ret[@]}" )
   qsort "${larger[@]}"
   larger=( "${qsort_ret[@]}" )
   qsort_ret=( "${smaller[@]}" "$pivot" "${larger[@]}" )
}

prt(){
  local i cnt=0
  for i
  do
    printf "$((cnt+=1)) %s\n" "$i"
  done
}

qsort "$@"
echo "
unsorted arguments:"
prt "$@"
echo "
sorted arguments:"
prt "${qsort_ret[@]}"

Proper quoting of variables in command arguments is important! Only then all special characters are treated normal, even newline characters.
--
You haven't provided your shell script yet. So maybe my assumptions were totally wrong...
# 4  
Old 06-16-2018
Quote:
Originally Posted by RudiC
Post your script.
line 27,28,54 to be re-arange
# 5  
Old 06-16-2018
Quote:
Originally Posted by MadeInGermany


.....
.....


--
You haven't provided your shell script yet. So maybe my assumptions were totally wrong...

The file to be re-aranged has been posted.

---------- Post updated at 16:34 ---------- Previous update was at 16:17 ----------

@Madeingermany
@Rudic


Took initial file.
Remove comments.
remove blank lines.
sort the file.
Add my header.


That give the file I just provide.

In that file :

line 28 must be the first position of the three (new position)
line 54 must follow in second position (new position)
line 27 must the last in third position (new position)


But the lines position are unknown.
Only the contents of the offending lines are known.


After reordering the result should be :
Code:
.........
.........
.........
.........
data_directory = /var/lib/postfix
debugger_command =
     PATH=/bin:/usr/bin:/usr/local/bin:/usr/X11R6/bin
     ddd $daemon_directory/$process_name $process_id & sleep 5
debug_peer_level = 2
........
.........
.........
.........

If you need more details then asks.
thank you for helping.

---------- Post updated at 16:49 ---------- Previous update was at 16:34 ----------

Should be something like :
Code:
Cut line with contents = 'ddd $daemon_directory/$process_name $process_id & sleep 5'

 Find line with contents = 'debugger_command ='


Paste the line after the find what one have cut before
  
Cut the line contents = 'PATH=/bin:/usr/bin:/usr/local/bin:/usr/X11R6/bin'

Find line with contents = 'debugger_command ='

Paste the line after the find what one have cut before

PS I know nothing about awk, and very few about sed.
# 6  
Old 06-18-2018
In post #1 you said that your input lines are terminated with 'CR', which I assume you meant to be a <carriage-return> character. But the sample file you uploaded (main.cf.txt) does not contain any <carriage-return> characters; instead it contains normal UNIX text files with lines terminated by <newline> characters.

In post #1 you showed us sample input data containing multiple adjacent lines starting with <tab>. In the file you uploaded, that never happens, but there are multiple occurrences of configuration lines followed by <tab>bed lines.

In post #1 you didn't mention anything about comment lines nor about empty lines that are not supposed to be sorted, but there are lines at the start of the file you uploaded that I assume are not intended to be sorted. (But, of course, that is a wild assumption because you have not really shown us what output should be produced by processing the file you uploaded.)

You also mention in post #1:
Quote:
But line 2 and 3 of the concerning parameter start with a tab char (but should be one or more space).
but there aren't any <tab> characters in your example in post #1 and there aren't any leading <space> characters in the file you uploaded.

Assuming that you want all lines starting with a "#" and all blank lines to appear unsorted at the start of the output file produced (in the order in which they were found in the input) and that the first lines of configuration data are to be sorted into alphanumeric order with continuation lines (any line that contains at least one non-blank character but with a first character that is a <space> or a <tab>) unsorted and attached to the configuration line it follows, the following bash script using awk and sort to preprocess data to be sorted, sort to sort the configuration data, and awk to post process the sorted data seems to do what I'm guessing you want:
Code:
#!/bin/bash
# Create a name for hte temporary output file to be used by sort.
sorted_cf="sorted.cf."$$

# Use awk to preprocess your input file:
#	directly printing comments and blank lines.
#	using sort to sort configuaration data, and
#	postprocess the sorted configuration data to print the sorted
#	    configuratoin data.
awk -v sorted_file="$sorted_cf" '
BEGIN {	# Set input and output field separators.
	FS = OFS = "\r"
	# Set sort command to be used to sort confiiguration data (not comments).
	sort = "sort -t\"\r\" -k1,1 -k2,2n -k3,3n -o " sorted_file
}
/^#/ || /^[ \t]*$/ {
	# Print comments and blank lines at start of output.
	print
	next
}
/^[ \t]/ {	
	# Filter non-blank lines starting with a blank by creating a line to be
	# sorted on the previous line not starting with a blank, a count of the
	# number of times that line has been seen, and a count of the lines seen
	# since that line was.  Also print (but do not sort) the contents of 
	# this line.
	print last, n[last], ++seq, $0 | sort
	next
}
{	# Filter non-blank lines starting with a non-blank by creating a line to
	# be sorted on the full contents of this line, the number of times this
	# line has been seen, and 1 (the number of lines in this set so far).
	print last = $0, ++n[$0], seq = 1 | sort
}
END {	# Close the output to be filtered through the sort utility.
	close(sort)
	# And read back i nthe sorted configuration data...
	while ((getline < sorted_file) == 1) {
		if(NF == 3)
			# For lines containing initial lines and counts, print
			# just the initial line data.
			print $1
		else if(NF == 4)
			# For lines containing initial lines, counts, and a
			# continuation line, print just the continuation line.
			print $4
	}
}' main.cf.txt # close the awk script and name the file to be processed.

# Remove the temporary output file produced by sort.
rm -f "$sorted_cf"

With the sample data you uploaded, this produces the output:
Code:
#####################################
#										#
#	{config_jcd}							#
#										#
#	/etc/postfix/main.cf
#										#
#	/etc/postfix/main.cf.lst.sort  sort no comments
#										#
#	INSTALL VERSION						#
#										#
#	§2018_06_15§							#
#										#
#	¨version:27-0-0¨						#
#										#
#	ɸmodif_version:0-0-1ɸ				#
#										#
#####################################

alias_maps = 
biff = no
canonical_maps = 
command_directory = /usr/sbin
compatibility_level = 2
content_filter = 
daemon_directory = /usr/lib/postfix
data_directory = /var/lib/postfix
	 ddd $daemon_directory/$process_name $process_id & sleep 5
debug_peer_level = 2
debugger_command =
defer_transports = 
delay_warning_time = 0h
disable_dns_lookups = no
disable_mime_output_conversion = no
disable_vrfy_command = yes
html_directory = /usr/share/doc/packages/postfix-doc/html
inet_interfaces = all
inet_protocols = ipv4
mail_owner = postfix
mail_spool_directory = /var/mail 
mailbox_command = 
mailbox_size_limit = 0
mailbox_transport = 
mailq_path = /usr/bin/mailq
manpage_directory = /usr/share/man
masquerade_classes = envelope_sender, header_sender, header_recipient
masquerade_domains = 
masquerade_exceptions = 
message_size_limit = 0
message_strip_characters = 
mydestination = $myhostname, localhost.$mydomain
myhostname = localhost
mynetworks_style = subnet
newaliases_path = /usr/bin/newaliases
	 PATH=/bin:/usr/bin:/usr/local/bin:/usr/X11R6/bin
queue_directory = /var/spool/postfix
readme_directory = /usr/share/doc/packages/postfix-doc/README_FILES
relay_clientcerts = 
relay_domains = $mydestination, hash:/etc/postfix/relay
relayhost = 
relocated_maps = 
sample_directory = /usr/share/doc/packages/postfix-doc/samples
sender_canonical_maps = 
sendmail_path = /usr/sbin/sendmail
setgid_group = maildrop
smtp_enforce_tls = no
smtp_sasl_auth_enable = no
smtp_sasl_password_maps = 
smtp_sasl_security_options = 
smtp_tls_CAfile = 
smtp_tls_CApath = 
smtp_tls_cert_file = 
smtp_tls_key_file = 
smtp_tls_session_cache_database = 
smtp_use_tls = no
smtpd_banner = $myhostname ESMTP
smtpd_client_restrictions = 
smtpd_delay_reject = yes
smtpd_helo_required = yes
smtpd_helo_restrictions = 
smtpd_recipient_restrictions = 
smtpd_sasl_auth_enable = no
smtpd_sender_restrictions = 
smtpd_tls_CAfile = 
smtpd_tls_CApath = 
smtpd_tls_ask_ccert = no
smtpd_tls_cert_file = 
smtpd_tls_key_file = 
smtpd_tls_received_header = no
smtpd_use_tls = no
strict_8bitmime = no
strict_rfc821_envelopes = no
transport_maps = 
unknown_local_recipient_reject_code = 550
virtual_alias_domains =

If this isn't what you're trying to do, please specify much more clearly exactly what it is that you're trying to do and show us the output you are trying to produce.
# 7  
Old 08-26-2018
Quote:
Originally Posted by Don Cragun
In post #1 you said that your input lines are terminated with 'CR', which I assume you meant to be a <carriage-return> character. But the sample file you uploaded (main.cf.txt) does not contain any <carriage-return> characters; instead it contains normal UNIX text files with lines terminated by <newline> characters.

Sorry I would say <newline>

Quote:
Originally Posted by Don Cragun
In post #1 you showed us sample input data containing multiple adjacent lines starting with <tab>. In the file you uploaded, that never happens, but there are multiple occurrences of configuration lines followed by <tab>bed lines.

The post #1 is my question.
The first block of code show the source file part where I have a problem.
The second bloc of code show the result of my script with the offending lines.
The third block (last block) show the result I need to get.
As said in #1 :
Quote:
the concerning parameter start with a tab char (but should be one or more space).


Quote:
Originally Posted by Don Cragun
In post #1 you didn't mention anything about comment lines nor about empty lines that are not supposed to be sorted, but there are lines at the start of the file you uploaded that I assume are not intended to be sorted. (But, of course, that is a wild assumption because you have not really shown us what output should be produced by processing the file you uploaded.)
.....
......

You also mention in post #1:
but there aren't any <tab> characters in your example in post #1 and there aren't any leading <space> characters in the file you uploaded.

In post #5 "---------- Post updated at 16:34 ---------- Previous update was at 16:17 ----------"
I explain what my script is doing
Quote:
Took initial file.
Remove comments.
remove blank lines.
sort the file.
Add my header.
And what must be corrected

That give the file I just provide.


In that file :

line 28 must be the first position of the three (new position)
line 54 must follow in second position (new position)
line 27 must the last in third position (new position)

But the lines position are unknown.
Only the contents of the offending lines are known.
[/QUOTE]



Quote:
Assuming that you want all lines

..............
.......
With the sample data you uploaded, this produces the output:


#####################################
# #
# {config_jcd} #
# #
# /etc/postfix/main.cf
# #
# /etc/postfix/main.cf.lst.sort sort no comments
# #
# INSTALL VERSION #
# #
# §2018_06_15§ #
# #
# ¨version:27-0-0¨ #
# #
# ɸmodif_version:0-0-1ɸ #
# #
#####################################

alias_maps =
biff = no
canonical_maps =
command_directory = /usr/sbin
compatibility_level = 2
.................
.................
.........
Quote:
If this isn't what you're trying to do, please specify much more clearly exactly what it is that you're trying to do and show us the output you are trying to produce.
As said in post #5, I need that line 27,28,54 re-ordered as shown in post #1 in last block of code.

Quote:
.............
.............
.............
content_filter = daemon_directory = /usr/lib/postfix

data_directory = /var/lib/postfix

debugger_command =

ddd $daemon_directory/$process_name $process_id & sleep 5

PATH=/bin:/usr/bin:/usr/local/bin:/usr/X11R6/bin debug_peer_level = 2 default_transport = error : outside mail is not deliverable

defer_transports =

.............
.............
.............
Login to Reply

« Previous Thread | Next Thread »
Thread Tools Search this Thread
Search this Thread:

Advanced Search
Display Modes

More UNIX and Linux Forum Topics You Might Find Helpful
Thread Thread Starter Forum Replies Last Post
How do i check if all parameters are set in bash? Jesshelle David Shell Programming and Scripting 5 09-08-2016 03:23 AM
How to call a bash script with positional parameters? vel4ever Shell Programming and Scripting 2 04-11-2013 01:40 PM
Bash Positional Parameters Question bashily Shell Programming and Scripting 2 04-03-2012 12:24 AM
Passing parameters to bash script function (or subroutine) withanh Shell Programming and Scripting 2 02-18-2012 07:00 PM
Ordering HTML Drop Down List entries Alphabetically jedel Shell Programming and Scripting 6 12-21-2010 08:34 AM
bash script function parameters programAngel Shell Programming and Scripting 2 12-05-2010 06:34 AM
Parameters passed to commands but not working in Bash shell Cypress Shell Programming and Scripting 10 12-07-2009 05:07 PM
bash if loop for checking multiple parameters szittyafergeteg Shell Programming and Scripting 2 02-23-2009 03:12 PM
Get the List of functions with modified parameters Sivaswami Shell Programming and Scripting 1 01-12-2009 09:23 AM
BASH: how to launch a program with parameters TinCanFury Shell Programming and Scripting 5 03-15-2008 04:02 AM


All times are GMT -4. The time now is 09:24 AM.

Unix & Linux Forums Content Copyright 1993-2018. All Rights Reserved.
UNIX.COM Login
Username:
Password:  
Show Password