我有这样的输入:
12 abc 13 14
13 def 14 15
1 lce 22 14
我想通过将程序./program
应用于第二列来更改它:
12 P1 13 14
13 P2 14 15
1 P3 22 13
(如果echo "abc" | ./program
返回" P1",echo "def" | ./program
返回" P2"等)。我该怎么做?
使用一段时间阅读循环:
while read -r one two rest
do
echo "$one $(./program <<< "$two") $rest"
done < inputfile
while read a b c d ; do echo $a $(./program <<< $b) $c $d ; done < t
其中 t
是文件的名称。
这应该做您想做尴尬脚本的事情
{
"echo "$2" | ./program" | getline result;
$2 = result;
print;
}
为什么不在awk
中全部使用,您需要"程序"?
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
它的工作原理
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
如果带有" P"数据的表不是续集,则可以像其他表一样添加它:
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"]}'
我认为最简单的方法是一段时间循环。
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
备注:
- 我使用
tr
,因为您的列可能会对齐。tr -s ' '
将多个空间替换为一个。 - 我正在使用SED来更改您的线路,以免与对齐方式混乱。
,如果 echo "abc" | ./program
返回" p1", echo "def" | ./program
返回" p2"等)。我该怎么做?
程序脚本可能看起来像:
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
之后... -
echo "abc" | sh program
返回" P1" -
echo "def" | sh program
返回" P2"
:如果您只希望输出为
12 P1 13 14
13 P2 14 15
1 P3 22 13
您可以使用以下单线:
awk 'BEGIN {OFS="t"} {$2="P"NR}1' input.txt > outfile.txt