1

I have an input like this:

12 abc 13 14
13 def 14 15
1  lce 22 14

And I want to change it by applying the program ./program to the second column:

12 P1 13 14
13 P2 14 15
1  P3 22 13

(if echo "abc" | ./program returns "P1",echo "def" | ./program returns "P2", etc.). How I can do that?

6 Answers 6

4

Use a while read loop:

while read -r one two rest
do
  echo "$one $(./program <<< "$two") $rest"
done < inputfile
Sign up to request clarification or add additional context in comments.

Comments

2
while read a b c d ; do echo $a $(./program <<< $b) $c $d ; done < t

where t is the name of the file.

Comments

1

This should do what you want as an awk script

{
   "echo "$2" | ./program" | getline result;
   $2 = result;
   print;
}

Comments

1

Why not take all in awk, do you need the "program"?

awk 'BEGIN {n=split("abc def lce",q," ");for (i=1;i<=n;i++) d[q[i]]="P"i} {sub($2,d[$2])}8' file
12 P1 13 14
13 P2 14 15
1  P3 22 14

How it works

awk '
BEGIN {                             # Begin block
    n=split("abc def lce",q," ")    # split the list of data in to array "q" and set "n" to number of elements
    for (i=1;i<=n;i++)              # loop trough  all elements
        d[q[i]]="P"i                # assing P1, P2 etc to first, second element "d[abc]=P1" etc
    } 
    {sub($2,d[$2])}                 # change filed 2 to new element
    8                               # print the new line
    ' file                          # input file

If table with "P" data is not sequel, you can add it just like other table:

awk 'BEGIN {n=split("abc def lce",q," ");split("P2 Q4 A3",r," ");for (i=1;i<=n;i++) d[q[i]]=r[i];print d["def"]}'

Comments

0

I think the easiest way would be with a while loop.

while read -r line; do
    old="$(echo "$line" | tr -s ' ' | cut -d ' ' -f 2)"
    new="$(echo "$old" | ./program)"
    echo "$line" | sed "s/$old/$new/"
done

Remarks:

  • I use tr because your columns might be aligned. tr -s ' ' replaces multiple spaces by one.
  • I'm using sed to change your line, in order not to mess with the alignment.

Comments

0

WITH REGARDS TO: if echo "abc" | ./program returns "P1", echo "def" | ./program returns "P2", etc.). How I can do that?

The program script might look something like:

INFILE=input.txt ## your input file

## exits if no standard input
if [ -t 0 ] ; then echo "Error: No STDIN" && exit ; fi

## do something
while read line; do
    awk -v input=$line '$2 == input {print "P"NR}' $INFILE
done
  • after you specify the INFILE in the program script...
  • echo "abc" | sh program returns "P1"
  • echo "def" | sh program returns "P2"

WHEREAS: if you just want the output to be

12 P1 13 14  
13 P2 14 15  
1  P3 22 13

You can use the following one-liner:

awk 'BEGIN {OFS="\t"} {$2="P"NR}1' input.txt > outfile.txt

3 Comments

The awk solution is not good. OP like to look up the value in an external script and replace in the file, not just number the line.
Sorry, but could you clarify what you mean? ... Oh, do you mean the "program" script is already written ..?
He like to change some text to some other text based on a table stored in his program. Eks if "qwr" change to "P84AA", not just a counting number,

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.