bash - 从具有不同分隔符的文件中提取几个以空格分隔的字段到 Bash 中的另一个文件中
问题描述
我有一个来自第三方 Windows 软件的 Unicode/UTF-8 文本文件,其中包含大约十列数据。
标题行是制表符分隔的。但是,剩余的行是空格分隔的(不是制表符分隔的!)(如在 Notepad++ 或 TextWrangler 中打开文件时所见)。
以下是文件的前四行(例如):xyz(ns) z(cm) z-abs(cm) longitude- E latitude- N type_of_object description 728243.03 5993753.83 0 0 0 143.537779835969 -36.1741232463362 linestart DRIVEWAYGRAVEL 705993 72824203。 0 0 143.537768534943 -36.1741037476109 linestart DRIVEWAYGRAVEL 728242.26 5993756.11 0 0 0 143.537770619485 -36.1741028922293 linestart DRIVEWAYGRAVEL
x y z(ns) z(cm) z-abs(cm) longitude- E latitude- N type_of_object description
728243.03 5993753.83 0 0 0 143.537779835969 -36.1741232463362 linestart DRIVEWAYGRAVEL
728242.07 5993756.02 0 0 0 143.537768534943 -36.1741037476109 line DRIVEWAYGRAVEL
728242.26 5993756.11 0 0 0 143.537770619485 -36.1741028922293 linestart DRIVEWAYGRAVEL
(注意每行开头的空格,标题行除外)
我正在尝试编写一个 Bash 脚本来重新格式化数据以导入不同的 Windows 程序。
(我意识到我可以在 Windows 命令行上执行此操作,但我没有这方面的经验,因此更愿意将文件复制到我的 Debian 机器上并在 Bash 中创建一个脚本。这意味着输入文件和输出文件需要与 Windows 兼容,但脚本本身显然是在 Linux 中运行的。)
我需要执行以下操作:
- 提取前两列(x 和 y 坐标),但仅适用于倒数第二列中包含“矩形”的行,使用逗号分隔符。
- 在每行末尾添加 1 或 0。第一行应该有 1,第 2-4 行应该有 0,第 5 行应该有 1,第 6-8 行应该有 0,依此类推。也就是说,每四行(从第一行开始)应该有一个 1,每隔一行应该有一个 0。
所以输出文件应该是这样的:
728257.89,5993759.24,1
728254.83,5993758.54,0
728251.82,5993762.4,0
728242.45,5993765.07,0
我已经尝试过这个问题的答案。例如
awk '
NR==1{
for(i=1;i<=NF;i++)
if($i!="z(ns)")
cols[i]
}
{
for(i=1;i<=NF;i++)
if(i in cols)
printf "%s ",$i
printf "\n"
}' input.file > output.file
...删除第三列(然后对此进行修改以删除其他不需要的列)。但是,我剩下的只是一个空的输出文件。
我还尝试使用 grep 和 awk 一起破解解决方案:
touch output.txt
count=0
IFS=$'\n'
set -f #disable globbing
for i in $( grep "rectangle" $inputFile )
do
Xcoord=$(awk 'BEGIN { FS=" " } { print $1 }' $i )
printf "$Xcoord" >> output.txt
echo ","
Ycoord=$(awk 'BEGIN { FS=" " } { print $2 }' $i )
printf "$Ycoord" >> output.txt
printf ","
count=$((count+1))
if [[ count = "1" ]]
then
printf "$count\n" >> output.txt
else
printf "0\n" >> output.txt
fi
done
set +f #re-enable globbing for future use of the terminal.
...这背后的想法是:-对于 $inputFile 中包含“矩形”的每一行
1. Append the first column (variable "Xcoord") to output.txt
2. Append a comma to output.txt
3. Append the second column (variable "Ycoord") to output.txt
4. Append another comma to output.txt
5. Append the 1 or 0 as per the if test based on the value of the variable "count", along with a new line.
这个想法失败了。它不是将数据保存到文件中,而是将文件的所有列打印到标准输出,第一列替换为文本“(没有这样的文件或目录)”:
...并且 output.txt 只是充满了零:
- 我怎样才能解决这个问题?
- 我需要做任何事情来使生成的 output.txt 文件为 Windows 格式吗?
提前致谢...
解决方案
我认为 awk 能够在一行中满足您的所有需求:
awk -F '[[:space:]][[:space:]]+' 'BEGIN{OFS = ","} {if ($8 == "rectangle") print $1, $2 }' a.txt | awk 'BEGIN{OFS = ","}{if((NR+3)%4) print $0,0;else print $0,1}'
您将条目之间的设置分隔符设置为“至少两个空格”
-F '[[:space:]][[:space:]]+
将输出分隔符设置为逗号
'BEGIN{OFS = ","}
检查倒数第二列中的矩形条件
if ($8 == "rectangle")
并打印您想要的列作为输出
print $1, $2
要在第三个输出列中添加 0,1 模式,您必须重新启动 awk 以获取结果文件的行号,而不是原始输入行。awk NR 变量包含从 1 开始的行号。
(NR+3)%4
(% 是模运算)对于第 1、5、9 行,结果为 0(=false),...所以您只需打印完整的行(变量 $0 ),然后在 if 情况下打印 0 和1 在其他情况下。
print $0,0;else print $0,1
希望这就是你想要的。
推荐阅读
- c - C99 中与调整参数相关的未定义行为
- python - String.Strip 在第二个 for 循环中跳过一个字符
- elasticsearch - 如何设计一种通用的搜索方法来搜索索引中的任何属性
- javascript - Sending data from frontend to backend in shopify
- ruby-on-rails - 如何使用 Rails(API JSON 响应)从 AWS S3 获取对象 URL(链接)
- excel - add .SendKeys to an existing macro
- npm - 当我离线时,npm mssql 包智能感知不起作用?
- google-bigquery - 使用 Spark Java 在 Big Query 中写入 Date 数据类型时出现问题
- python - 使用 TensorFlow 从检查点重新开始训练后保留训练/验证拆分
- java - 供应商作为一种功能