【问题标题】:Avoid newline when combining two variables and outputing to file组合两个变量并输出到文件时避免换行
【发布时间】:2015-02-13 12:35:59
【问题描述】:

我正在尝试运行这样的 sh 脚本来收集有关 IP 地址的地理信息。 inputfile.txt 只是一个包含 IP 地址的单列文件。

这是我的输入文件的示例:

213.100.122.171
213.100.126.188
213.100.129.186
213.100.18.247
213.100.23.238
213.100.26.151

这是我正在使用的代码:

#!/usr/bin/env bash
output=outputfile.csv
for  i in $( cat "inputfile.txt"); 
do echo -e "$i,"$( geoiplookup -f /usr/share/GeoIP/GeoLiteCity.dat $i | cut -d' ' -f6,8-9)"" >> $output;
done

当我运行这个文件时,结果是这样的

213.100.126.188
,LV, N/A, N/A,
213.100.129.186
,SE, N/A, N/A,
213.100.18.247
,LV, N/A, N/A,
213.100.23.238
,LV, N/A, N/A

我希望他们在各自的行中,比如

213.100.126.188,LV, N/A, N/A,
213.100.129.186,SE, N/A, N/A,
213.100.18.247,LV, N/A, N/A,
213.100.23.238,LV, N/A, N/A,

我的脚本哪里出错了?

【问题讨论】:

  • 你在很多地方都错了:for i in $(cat "inputfile.txt"); do 错了。 inputfile.txt的内容是什么?顺便说一句,去向给你看这个的人抱怨。真的去做。你有 $(geoiplookup ...) 未引用。这很糟糕(取决于路径名扩展)。您在那里也使用了未引用的变量$i。您正在为每个 ip 打开和关闭文件 outputfile.csv,这只是无用的资源消耗。将重定向放在循环的末尾。当然,这些都不能解决你的问题!

标签: bash echo cat


【解决方案1】:

for 循环与cat 一起使用不是逐行处理文件的好方法。我建议将您的脚本更改为以下内容:

#!/bin/bash

output=outputfile.csv    
while read -r line; do
    echo -e "$line, $( geoiplookup -f /usr/share/GeoIP/GeoLiteCity.dat "$line" | cut -d' ' -f6,8-9)"
done < inputfile.txt > "$output"

这将截断输出文件并将循环的所有输出写入其中。将命令替换和参数扩展括在双引号中可以防止命令输出中的字符扩展问题。

【讨论】:

  • 不幸的是,结果是一样的:/
  • 作为gniourf_gniourf has mentioned above,查看输入文件的内容会很有用。也许您可以编辑您的问题以包含其内容示例
  • 添加了示例。文件中只有一列带有 IP 地址。仅此而已。
  • @jam 你用的是什么系统?
【解决方案2】:

它很可能是产生换行符的应用程序geoiplookup。所以你必须通过管道将输出槽sed 删除:

for  i in $( cat "inputfile.txt"); 
  do echo -e "$i,"$( geoiplookup -f /usr/share/GeoIP/GeoLiteCity.dat $i | \
  cut -d' ' -f6,8-9 | sed ':a;N;$!ba;s/\n/)"" >> $output;
done

【讨论】:

  • 需要命令替换后的换行符。这是导致问题的原因是尝试使用forcat 逐行读取文件。
  • Bash 用$(...) 去除所有尾随换行符,所以这不是答案。试试看:a=$(echo test; echo; echo; echo; echo; echo); declare -p a。您将看不到尾随的换行符。此外,由于$(...) 在引号之外,Bash 将完全删除所有换行符。我可以肯定地说,你在这里是双重错误的。 (但我不是反对者!)。
  • @TomFenech 我有一个名为input 的文件有3 行,执行for i in $( cat "input"); do echo -e "-$i-"; done 会打印$i 之后没有换行符的所有行。如果文件末尾有\necho -e 会将它们解释为换行符,但在我们的例子中不是这样。我是不是理解错了?
【解决方案3】:

好的,我发现了问题。输入文件的第一行是空的,脚本不知何故决定按照我的描述工作。当我删除那个空行时,一切正常。

【讨论】:

    猜你喜欢
    • 2020-09-30
    • 2018-04-16
    • 2022-08-20
    • 2016-08-15
    • 2016-02-06
    • 1970-01-01
    • 2020-08-24
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多