我正在创建一个Shell脚本来分析输入文件并将结果发送到输出文件。这是来自输入文件的示例:
01,Rome,30,New York,70,
02,Los Angeles,5,New York,50,
03,New York,40,Tokyo,20,
04,Paris,5,New York,40,
05,New York,20,London,30,
06,Seattle,20,New York,40,
07,Chicago,10,New York,30,
08,New York,20,Miami,40,
这是我在输出文件中需要的结果:
01,Rome,30,New York,70,4th,40,
02,Los Angeles,5,New York,50,4th,45,
03,New York,40,Tokyo,20,2nd,20,
04,Paris,5,New York,40,4th,35,
05,New York,20,London,30,2nd,-10,
06,Seattle,20,New York,40,4th,20,
07,Chicago,10,New York,30,4th,20,
08,New York,20,Miami,40,2nd,-20,
字段之间用逗号分隔。
我打算在每行的第二个字段中搜索字符串“ New York”,如果为true,则将第6个字段添加为“ 2nd”,如果不是,则添加值为“ 4th”的第6个字段
然后,我打算使用第三和第五字段中的值进行减法运算。如果第6个字段中的字符串是“第4个”,请从第5个字段中减去第3个字段。如果第6个字段中的字符串是“ 2nd”,请从第3个字段中减去第5个字段。计算结果必须是每行的第7个字段。
我尝试了awk,sed,grep,echo和bc的组合,但是我觉得我想得太多了。有什么建议吗?
编辑:到目前为止,我的进步-我认为单独评估和附加每行效率不高。
while read line; do
echo "$(cut -f2 -d ",")"
done < input.txt
打印每行的第二个字段,但是我对评估字符串并将这些行添加到循环中感到困惑。对于减法部分,我的计划是对bc使用echo和pipe值,但此刻我仍停留在第一步。
答案 0 :(得分:0)
我认为awk
是最简单的工作,这里是使用sed
的替代方法:
sed -r 's/.*,New York,([0-9]*),.*,([0-9]*),/echo "&2nd,$((\1 - \2))"/e;
s/.*,.*,([0-9]*),New York,([0-9]*),/echo "&4th,$((\2 - \1))"/e' input.txt
EDIT,说明:
将/e;
更改为/;
并删除最后一个e
时,您会看到更好的结果。
输入行中以纽约作为第二个字段的部分匹配:
.*, # First field. It will not eat the whole line, because
# the rest of the line must match too.
New York, # Match on the second field
([0-9]*), # The match on the number in parentheses, so it can be used later.
.*, # next field
([0-9]*), # Second string to remember. I edited the answer, first I had `([0-9]*).`
# what worked (`.` is a wildcard), but `,` is better.
进行计算时,我们需要外壳。 Shell可以不使用bc
之类的东西而进行echo "$((8 - 5))"
的计算。
替换字符串将可以执行。
echo "..." # Command to echo the things in quotes
& # Replace with the complete match, in our case the complete line
2nd, # Nothing special here.
$((...)) # Perform calculation
\1 # Replace with first remembered match (between parentheses)
\2 # Replace with second remembered match (between parentheses)
sed
支持/e
执行结果。 (请勿尝试使用/e
设置变量,它将在子shell中执行,并且该变量在执行后会丢失。)。
对于纽约作为第四领域重复上述构造。
答案 1 :(得分:-1)
首先替换文件中的空格,因为这样会更容易工作
cat inputfile | sed 's/ /_/g' > tmp && mv tmp inputfile
然后定义一个测试变量:
test=New_York
现在是主要过程:
for i in $(cat inputfile)
do
if [[ $(echo "$i" | cut -d',' -f2) == "$test" ]]
then
int1=$(echo "$i" | cut -d',' -f5)
int2=$(echo "$i" | cut -d',' -f3)
result=$(expr "$int2" - "$int1")
echo $i | sed "s/$/2nd,$result/g" >> outputfile
else
int1=$(echo "$i" | cut -d',' -f3)
int2=$(echo "$i" | cut -d',' -f5)
result=$(expr "$int2" - "$int1")
echo $i | sed "s/$/4th,$result/g" >> outputfile
fi
done
如果要将空格放回文件中:
cat outputfile | sed 's/_/ /g' > tmp && mv tmp outputfile