我一直在使用 bash 将一些数据输出到多行文件,并以这种格式存储每行的数据:
text1 "text2" text3 integer1,integer2
“空格”分隔每行中的前四列数据。逗号分隔两个整数。 text2 用引号引起来。
现在我想使用 bash 来评估原始数据文件的每一行,然后根据使用不同的公式来评估整数 1 和整数 2,用新数据替换整数 1 和整数 2。
然后,结果应输出到一个新文件(与原始文件格式相同),如下所示:
text1 "text2" text3 Newinteger1,Newinteger2
答案1
我希望我不会让您对这段代码感到困惑,请参阅以 # 开头的注释。
我将使用以下输入文件进行测试:
text1 "text2" text3 1,2
this "/usr/strange path with spaces/" works 2,3
下一个脚本的输入可以给出为cat input | while ...
。 shell 提供了一个很好的方法来避免额外的过程cat
,即< input
脚本最后一行完成之后的过程。现在重要的是要记住,您将在阅读第二行之前解析一行。我将存储该行的变量称为line
,它可能是其他东西,例如 mybuf、firststring 或任何你想要的东西。
那么让我们开始吧。
while read -r line; do
# variable line is filled, just echo for debugging
echo "The var line is filled with ${line}."
# Special handling: you can cut off everything starting at the last space
mystrings=${line% *}
# You can also throw away everything up to a space.
# Two # characters for throwing away the largest substring with "* "
myints=${line##* }
# Did it work? Two echoes just checking
echo "mystring=${mystrings}"
echo "myints=${myints}"
# I'll try that strange thing with cutting up a variable again.
# Now I want to cut the myint into two integers
int1=${myints%,*}
int2=${myints#*,}
echo "My results are int1=${int1} and int2=${int2}"
# Some calculation.
# The value of the vars can be used without the $ when used in (( ...))
# Example new values: int1 will be given the original value of int2 + 5,
# int2 will be doubled.
# I did not add checks to see if int1 and int2 are integers
(( int1 = int2 + 5 ))
(( int2 = 2 * int2 ))
# And show the result
echo "${mystrings} ${int1},${int2}"
done < input
当您想确切地了解发生了什么时,可以使用启动脚本set -x
(打开调试,使用 再次关闭set -
)。
答案2
awk 的可能解决方案
#!/usr/bin/awk -f
{ split($4, a, ","); printf("%s %s %s %d,%d\n", $1, $2, $3, a[1] / 2, a[2] + 500); }
split 命令将 $4 列中的两个整数放入数组 a[] 中。 printf 命令打印到标准输出。三个占位符 %s 分别对应三个文本列 $1、$2 和 $3。两个 %d 占位文件夹是两个整数。根据您的需要更改两个整数值的计算。
将其保存到文件(例如 awktest)并将权限设置为
chmod +x ./awktest运行它
./awktest < 输入.txt > 输出.txt
答案3
awk -F'[ ,]' '{$(NF-1)=$(NF-1)*6 "," $NF-10 ; NF=NF-1}1' multiline.file
-F'[ ,]'
设置,
或<space>
作为分隔符$NF
— 最后一个字段$(NF-1)
— 最后一个字段由更改的最后一个字段和最后一个之前的字段组成$NF=$NF-1
— 删除最后一个字段1
— 打印组合行