LinuxQuestions.org
Support LQ: Use code LQ3 and save $3 on Domain Registration
Go Back   LinuxQuestions.org > Forums > Linux Forums > Linux - Newbie
User Name
Password
Linux - Newbie This Linux forum is for members that are new to Linux.
Just starting out and have a question? If it is not in the man pages or the how-to's this is the place!

Notices


Reply
  Search this Thread
Old 05-15-2012, 08:39 PM   #16
ust
Senior Member
 
Registered: Mar 2003
Location: fasdf
Distribution: Debian / Suse /RHEL
Posts: 1,130

Original Poster
Rep: Reputation: 30

Quote:
Originally Posted by allend View Post
I am assuming that you want a formatted display of a crontab file. It is much easier to help when good examples of input file format and desired output file format are supplied. It is also more likely that you will get help when you demonstrate some application to the task, such as reading manual pages, writing posts carefully with attention to spelling and use of proper language rather than text messaging abbreviations.
I show a file ust.txt containing this data

Despite my reservations about this being a homework assignment, here is a bash script that seems to do what you want.
Code:
#!/bin/bash

while read -a line; do 
  echo -n ${line}
  for (( i=1; i<${#line[*]}; i++ )); do
    if [[ $i < 5 ]]; then
      echo -ne "\t"${line[$i]};
    else
      echo -n " "${line[$i]};
    fi
  done
  echo
done < ust.txt
Hi ,

e.g. cat <file> | tr "[:space:]" "\t" <<== when use it , it delimit the whole file (all columns in the file) by "space" , can advise if I just want to delimit the first 5 column , what can i do ?

thx
 
Click here to see the post LQ members have rated as the most helpful post in this thread.
Old 05-15-2012, 10:12 PM   #17
allend
Senior Member
 
Registered: Oct 2003
Location: Melbourne
Distribution: Slackware-current
Posts: 4,430

Rep: Reputation: 1349Reputation: 1349Reputation: 1349Reputation: 1349Reputation: 1349Reputation: 1349Reputation: 1349Reputation: 1349Reputation: 1349Reputation: 1349
Copy the bash script into a file named ctformat.sh.
Execute 'sed -i s/ust.txt/\$1/ ctformat.sh'
Execute 'chmod +x ctformat.sh'
Execute './ctformat.sh <file>'
 
Old 05-16-2012, 02:48 PM   #18
David the H.
Bash Guru
 
Registered: Jun 2004
Location: Osaka, Japan
Distribution: Debian sid + kde 3.5 & 4.4
Posts: 6,823

Rep: Reputation: 1957Reputation: 1957Reputation: 1957Reputation: 1957Reputation: 1957Reputation: 1957Reputation: 1957Reputation: 1957Reputation: 1957Reputation: 1957Reputation: 1957
Some comments about allend's script.

1)
Code:
for (( i=1; i<${#line[*]}; i++ )); do
When iterating over an array, there's a more convenient option.

Code:
for i in "${!line[@]}" ; do
This outputs a list of all the available index numbers. It's particularly convenient for iterating over sparse arrays.


2)
Code:
if [[ $i < 5 ]]; then
This is just wrong. First of all, when inside square brackets, "<" is a string comparison operator. Try comparing the numbers 99 and 100 with it, for example.

The proper operator to use for integers is "-lt". Or even better, use actual arithmetic evaluation brackets.

Code:
if [[ $i -lt 5 ]]; then		#correct

if (( i < 5 )); then		#best
http://mywiki.wooledge.org/ArithmeticExpression
http://mywiki.wooledge.org/BashFAQ/031


3)
Code:
echo -ne "\t"${line[$i]};
Put the quotes around the entire string. You should never leave quotation marks off a parameter expansion unless you explicitly want the resulting string to be word-split by the shell. Globbing patterns get expanded too.

Code:
echo -ne "\t${line[$i]}"
http://mywiki.wooledge.org/Arguments
http://mywiki.wooledge.org/WordSplitting
http://mywiki.wooledge.org/Quotes



In any case, we can make the script much shorter and cleaner. Just use a single, simple printf statement to define the line format, and the array range expansion operators.

Code:
#!/bin/bash

while read -a line || [[ -n $line ]]; do

	printf '%s\t%s\t%s\t%s\t%s %s\n' "${line[@]:0:5}" "${line[*]:5}"

done < "$1"

exit 0
Notice in particular how I used "@" for the first five array entries, and "*" for the remainder. "@" means it outputs the vales 0-4 as separate entities, but "*" prints the values 5+ as a single string, so printf reads them as only one "%s" value.

I also set the filename to "$1" so that it can be run dynamically. It's not generally advisable to store things like filenames inside the script itself. Scripts are for containing code, not data.

Edit: One last modification. When using a while+read loop, if the input file doesn't contain a final newline, then the last line won't get processed. So I added an additional test to the while loop to capture and process it.

Last edited by David the H.; 05-16-2012 at 03:06 PM. Reason: as stated + wording
 
2 members found this post helpful.
Old 05-16-2012, 08:20 PM   #19
allend
Senior Member
 
Registered: Oct 2003
Location: Melbourne
Distribution: Slackware-current
Posts: 4,430

Rep: Reputation: 1349Reputation: 1349Reputation: 1349Reputation: 1349Reputation: 1349Reputation: 1349Reputation: 1349Reputation: 1349Reputation: 1349Reputation: 1349
Thanks David the H. - Very instructive as always.
 
Old 05-25-2012, 03:15 AM   #20
ust
Senior Member
 
Registered: Mar 2003
Location: fasdf
Distribution: Debian / Suse /RHEL
Posts: 1,130

Original Poster
Rep: Reputation: 30
Quote:
Originally Posted by allend View Post
Copy the bash script into a file named ctformat.sh.
Execute 'sed -i s/ust.txt/\$1/ ctformat.sh'
Execute 'chmod +x ctformat.sh'
Execute './ctformat.sh <file>'
hi allend ,

actually , I am not understand what is the step , can you please give me a instruction ?

thanks much.
 
Old 05-26-2012, 01:13 PM   #21
allend
Senior Member
 
Registered: Oct 2003
Location: Melbourne
Distribution: Slackware-current
Posts: 4,430

Rep: Reputation: 1349Reputation: 1349Reputation: 1349Reputation: 1349Reputation: 1349Reputation: 1349Reputation: 1349Reputation: 1349Reputation: 1349Reputation: 1349
Quote:
actually , I am not understand what is the step , can you please give me a instruction ?
Sorry, but I do not understand your problem. Is it that:
You cannot copy the bash script in the last code block in David the H.'s post (#18 in this thread) into a file with a name of your choosing which can be denoted <filename>?
You cannot open a bash shell in the directory containing this file <filename>?
You cannot type 'chmod +x <filename>' at the bash prompt and hit enter so that the file is made executable?
You cannot then type './<filename> <file>' and hit enter so that the bash script is executed using the data in <file>, where <file> may also be a path and filename specification?
 
  


Reply


Thread Tools Search this Thread
Search this Thread:

Advanced Search

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is Off
HTML code is Off



Similar Threads
Thread Thread Starter Forum Replies Last Post
compare second column of a file then print the first column of it in a ne fil if true java_girl Linux - Newbie 2 03-16-2012 05:50 AM
[SOLVED] Is it possible to use the ls command to list files in one column? BobNutfield Slackware 23 09-21-2010 03:13 AM
Bash script to suppress matches in two column list xsyntax Linux - General 6 09-03-2010 06:08 AM
error unknown column 'xxx' in field list rajesh84210 Linux - Newbie 4 09-08-2009 12:22 AM
Read text file column by column RVF16 Programming 11 05-31-2009 08:16 AM


All times are GMT -5. The time now is 01:09 AM.

Main Menu
Advertisement
My LQ
Write for LQ
LinuxQuestions.org is looking for people interested in writing Editorials, Articles, Reviews, and more. If you'd like to contribute content, let us know.
Main Menu
Syndicate
RSS1  Latest Threads
RSS1  LQ News
Twitter: @linuxquestions
Facebook: linuxquestions Google+: linuxquestions
Open Source Consulting | Domain Registration