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 =) 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).

12
  • 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
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
    Dec 19 '12 at 19:45
  • 1
    Sure, I do it now Dec 19 '12 at 19:47
  • 1
    Sorry, a quote forgotten =) Dec 19 '12 at 19:54
  • 1
    Be precise. Have you tested the 3 different versions ? 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. 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
0

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.