Bash 列值扩展到多行
我的档案如下:Bash 列值扩展到多行,bash,parsing,Bash,Parsing,我的档案如下: 1984 32768 5240.70 32768 5259.46 32768 5203.42 2016 32768 5244.38 32768 5223.40 32768 5263.07 2048 32768 5233.59 32768 5241.35 32768 5212.37 我想转换成这种格式: 1984 32768 5240.70 1984 32768 5259.46 1984 32768 5203.42 2016 32768 5244.38 2016 3
1984
32768 5240.70
32768 5259.46
32768 5203.42
2016
32768 5244.38
32768 5223.40
32768 5263.07
2048
32768 5233.59
32768 5241.35
32768 5212.37
我想转换成这种格式:
1984 32768 5240.70
1984 32768 5259.46
1984 32768 5203.42
2016 32768 5244.38
2016 32768 5223.40
2016 32768 5263.07
2048 32768 5233.59
2048 32768 5241.35
2048 32768 5212.37
使用bash可以轻松实现这一点吗?单线解决方案会更好。这里是单线解决方案:)
读取时-arr;如果[${arr[@]}-eq 1];然后第一个=$arr;elif[${arr[@]}-gt 0];然后回显$first“${arr[@]}”;fi;完成output_file.dat
您可能更愿意将其作为一个函数使用,尽管您可以将其存储在~/.bash\u别名中
或~/.bashrc
convert_文件(){
input_file=“$1”
读取时-a arr;将行中的每个单词放入数组“arr”
如果[${arr[@]}-eq 1];则#行上只有一项
first=$arr#设置“first”值
elif[${arr[@]}-gt 0];然后#忽略空行(行上的项目超过零)
echo$first“${arr[@]}”#输出“first”值,然后是行
fi
完成<“$input_file”#将输入文件馈送到读取循环
}
这样称呼它:
转换文件输入文件.dat>输出文件.dat
对上述情况的解释:
这是命令行中的第一个参数$1
循环输入并将每行上的每个字加载到数组“arr”中的一个元素中读取时-arr
测试数组“arr”([${arr[@]}-eq 1]
)的长度是否在数学上等于(${arr[@]}
)1(即,我们在这行上只有一个单词)-eq
- 在bash中,数组有点奇怪。如果要查看整个数组,则需要
和大括号-[@]
。在数组变量名称前面加上${arr[@]}
表示长度#
-first=$arr
是从数组中获取第一个元素的惰性方法,但它可以工作:)$arr
测试数组“arr”([${arr[@]}-gt 0]
)的长度在数学上是否大于(${arr[@]}
)零(即我们没有空行)-gt
输出“first”值,后跟数组“arr”的内容echo$first“${arr[@]}”
-done<“$input\u file”
将output_file.dat
函数的输出重定向到文件convert_file
。注意:文件将首先被截断!使用output_file.dat
而不是>
附加到给定文件
- 与awk中的@Kind相同的逻辑:
awk '1 == NF { key=$1 }; 2 == NF { print key " " $0 };' file
我喜欢纯bash
,但是awk
对于任何大小的文件都会更快、更高效
作为练习,在sed
中实现;o]
sed -En '/^ *$/d; /^[0-9]{4}$/h; /^[0-9]{5} /{ x; G; s/\n/ /g; p; s/ .*//; h; }' file
并解释说:
sed -En ' # -E use extended pattern matching. -n only print when requested
/^ *$/d; # delete blank lines
/^[0-9]{4}$/h; # store header lines
/^[0-9]{5} /{ # for data lines,
x; # swap the hold and pattern spaces
G; # add the hold (data) to the pattern (header)
s/\n/ /; # remove the newline between
p; # print the resulting line
s/ .*//; # remove the data
h; # put the header back into the hold space
} ' file
另一个例子,一个小小的状态机:
awk'
y | | NR==1{年=$1;getline;y=0;下一个}
NF==0{y=1;next}
{打印年份,$0}
"档案"
但是再看一遍,它会被连续的空行打断。@Kadir希望这个解释对你有用case语句更简洁一点:
case${arr[@]}in 0:;;1) 年份=${arr[0]};;*)回音“$year${arr[*]}”;;esac
良好点,已删除。