Reputation: 55
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?
Upvotes: 1
Views: 106
Reputation: 41460
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"]}'
Upvotes: 1
Reputation: 3279
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
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
Upvotes: 0
Reputation: 431
This should do what you want as an awk script
{
"echo "$2" | ./program" | getline result;
$2 = result;
print;
}
Upvotes: 1
Reputation: 5218
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:
tr
because your columns might be aligned. tr -s ' '
replaces multiple spaces by one.Upvotes: 0
Reputation: 59395
while read a b c d ; do echo $a $(./program <<< $b) $c $d ; done < t
where t
is the name of the file.
Upvotes: 2
Reputation: 123750
Use a while read loop:
while read -r one two rest
do
echo "$one $(./program <<< "$two") $rest"
done < inputfile
Upvotes: 4