4

I have a file that contains:

1 2 3 4
1 3 5 4 8
3 2 1 

Each line has a different number of digits. And there are 1000 more like this.

I want the output like this:

1 2
2 3
3 4
4 0
1 3
3 5
5 4
4 8
8 0
3 2
2 1
1 0

edit made to this post!!

i mean if this is last digit in line put that digit and then zero besides it.

for example if digit is last in that line we put in output new line that digit and zero

4 0 and others:see output sample tnx

in above example and

How can I do that, in perl awk or bash

i use this but its not working :((

awk '{
for (i=1; i<NF; i++)
{
if ( $(i+1) == "")
print $i, "0"
else
print $i, $(i+1)
}
}' UniqASinline> inTestAst

the outpute file of Mr.glenn jackman way:

for this imput:

3549 
3549 10026 
3549 10026 10010 
3549 10026  
awk '{for (i=1; i<=NF; i++) printf("%d %d\n", $i, $(i+1))}' filename

3549 
3549 10026
10026 
3549 10026
10026 10010
10010 
3549 10026
10026

but we expect:

3549 0
3549 10026
10026 0
3549 10026
10026 10010
10010 0
3549 10026
10026 0

tnx

2
  • Sounds like a homework =) Commented Dec 19, 2012 at 19:38
  • i can do it by sending item into array and then process the array but if we have 1000 lines its too slow in bash :(( !!!!
    – Arash
    Commented Dec 19, 2012 at 19:42

3 Answers 3

3
awk '{for (i=1; i<NF; i++) print $i, $(i+1)}' filename

EDIT: to reflect your new requirement

awk '{for (i=1; i<=NF; i++) printf("%d %d\n", $i, $(i+1))}' filename
# ----------------^ 

This takes advantage of the fact that awk treats uninitialized values (here $(NF+1)) as an empty string (in string context) or zero (in numeric context).

12
  • oh i'm sorry ive change the out put i need this , in above post edited
    – Arash
    Commented Dec 21, 2012 at 9:50
  • i mean if this is last digit in line put that digit and then zero besides it.
    – Arash
    Commented Dec 21, 2012 at 9:59
  • how could i chane this awk?? tnx alot
    – Arash
    Commented Dec 21, 2012 at 10:11
  • i want too put 0 not free space
    – Arash
    Commented Dec 21, 2012 at 16:11
  • tnx but your script is doing 1 2,2 3,3 4,4""(free space not "0")
    – Arash
    Commented Dec 21, 2012 at 16:13
3

Try doing this in

 perl -lane '$c=0; for (@F){ print "$F[$c]\t$F[$c+=1]" if $F[$c+1]}' file.txt

Or decomposed :

perl -lane '
    $c=0;
    for (@F) {
        print "$F[$c]\t$F[$c+=1]"
            if $F[$c+1];
    }
' file.txt

EXPLANATIONS

  • lane switchs means : l=newlines ; a=autosplit in @F array ; n=like while (<>) magic diamond operator ; e=basic switch to run a command
  • $c=0 assign 0 to a counter
  • for (@F) { for each element of the current line
  • print "$F[$c]\t$F[$c+=1]" : print array element with indice $c + tab + $c+1
  • if $F[$c+1]; : apply last line only if $F[$c+1] is not null

Or using (same algorithm), maybe more human readable for beginners :

while read a; do
    arr=( $a )
    for ((i=0; i< ${#arr[@]}; i++)); do
        [[ ${arr[i+1]} ]] && echo "${arr[i]} ${arr[i+1]}"
    done
done < file.txt
8
  • 2
    While this (probably, can't test) gives the OP what they want, it would be nice to explain what exactly it does, so that everyone seeing it can learn a little.
    – slhck
    Commented Dec 19, 2012 at 19:45
  • 1
    Sure, I do it now Commented Dec 19, 2012 at 19:47
  • 1
    Sorry, a quote forgotten =) Commented Dec 19, 2012 at 19:54
  • 1
    Be precise. Have you tested the 3 different versions ? Commented Dec 19, 2012 at 20:07
  • 2
    Can you show us a little bit of search effort ? Google have tons of results for this kind of things :/ If it's really a homework, in 1 week you will forget all this stuff... Sniff. Commented Dec 19, 2012 at 20:14
3

Here's a pure bash solution:

while read -a a; do
    for ((i=0;i<${#a[@]}-1;++i)); do
        echo "${a[@]:i:2}"
    done
done < file.txt
0

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .