Reputation:
I need to get first 9 words from a pipe delimited file and then next 9 words. Any help is appreciated.
cat a.txt
a|b|c|d|e|f|g|h|i|j|k|l|m|n|o|p|q|r|s|t|u|v|w|x|y|z|
cat new.ksh
#! /bin/ksh
a=`awk -F "|" ' { print NF-1 } ' a.txt`
echo $a
Expected Output:
a|b|c|d|e|f|g|h|i|
j|k|l|m|n|o|p|q|r|
s|t|u|v|w|x|y|z
Upvotes: 0
Views: 175
Reputation: 1313
I pure ksh
version:
IFS='|'
typeset -a str=( $( < a.txt ) )
len=${#str[@]}
bar='|'
for ((ii=0; ii<len; ii+=9))
do
max=9
(( ii+9 > len )) && max=$(( len-ii ))
for ((jj=0; jj<max; jj++))
do
element=$(( ii+jj ))
(( element == len-1 )) && bar=''
echo -e "${str[$element]}${bar}\c"
done
echo
done
Explanation:
IFS
: This is the Internal field separator, normally this is space and tab but if it is reassigned, it separates other types of data.typeset -a
We are creating an array to hold the data.str=( $( < a.txt ) )
We read in the data from the a.txt array as elements of the array.len=${#str[@]}
We need to know how long the array is so we know how much to print out.(( ii+9 > len )) && max=$(( len-ii ))
This is doing an integer comparison of ii+9 against the length. If the condition is true, we update max with the lower value.element=...
We want the ii+jj element so here we calculate the value.(( element == len-1 )) && bar=''
You had no bar at the end. To avoid printing the bar, we use a bar variable that we turn to nothing when done.echo -e "${str[$element]}${bar}\c"
Here we print that element along with the bar variable. The \c says do not end the print with a newline. The -e is required to get the \c to work.echo
Since we did not get linefeeds for each element, we need to put it out now that we have 9 elements.This version also works with bash.
Upvotes: 0
Reputation: 20002
sed -r 's/([^|]*\|){9}/&\n/g' a.txt
Explanation:
[^|]
Not a |.
[^|]*\|
One field (without |
), followed by a |
.
([^|]*\|){9}
9 fields, each followed by a |
.
&\n
Replace by the matched string followed by a newline.
Upvotes: 1