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

  • Sounds like a homework =) – Gilles Quenot Dec 19 '12 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 Dec 19 '12 at 19:42
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).

  • oh i'm sorry ive change the out put i need this , in above post edited – Arash Dec 21 '12 at 9:50
  • i mean if this is last digit in line put that digit and then zero besides it. – Arash Dec 21 '12 at 9:59
  • how could i chane this awk?? tnx alot – Arash Dec 21 '12 at 10:11
  • i want too put 0 not free space – Arash Dec 21 '12 at 16:11
  • tnx but your script is doing 1 2,2 3,3 4,4""(free space not "0") – Arash Dec 21 '12 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
  • 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 Dec 19 '12 at 19:45
  • 1
    Sure, I do it now – Gilles Quenot Dec 19 '12 at 19:47
  • 1
    Sorry, a quote forgotten =) – Gilles Quenot Dec 19 '12 at 19:54
  • 1
    Be precise. Have you tested the 3 different versions ? – Gilles Quenot Dec 19 '12 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. – Gilles Quenot Dec 19 '12 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

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.