重新格式化表格

ste*_*eve 2 bash text-processing

我有以下类型的表:

ID   date     DailyFlow
a 1972-01-01 17.0265761797993
b 1972-01-02 17.200476457399
c 1972-01-03 17.2926436045271
d 1972-01-04 17.3900277599829
e 1972-01-05 17.5987080931028
f 1972-01-06 17.6334881486229
g 1972-01-07 17.7030482596626
...
Run Code Online (Sandbox Code Playgroud)

我想将它们重新格式化如下:

YYYY    DDD sim
1972    1   17.0265761797993
1972    2   17.200476457399
1972    3   17.2926436045271
1972    4   17.3900277599829
1972    5   17.5987080931028
1972    6   17.6334881486229
1972    7   17.7030482596626
1972    8   17.7204382874227
Run Code Online (Sandbox Code Playgroud)

第一行包含在表中。这些文件是带有“制表符”分隔符的纯文本 (*.txt)。ID 列是一个虚拟的列,我想摆脱它!在我想要的输出中,DDD 列上的数字 (1,2,3,...) 应与相应年份的日期相符。

有没有人知道如何做到这一点(使用 bash)?谢谢!

kos*_*kos 7

这本来是 的工作awk,但第二列中的替换将需要gensub,因此gawk,默认情况下未安装,因此我最终得到了一个sed解决方案:

sed -i.bak 's/[^\t]*\t\([^-]*\)-[0-9][0-9]-[0-9]\([0-9]\)[^\t]*\t\([^\t]*\)/\1\t\2\t\3/' infile
Run Code Online (Sandbox Code Playgroud)

或者,使用 ERE 缩短(感谢 user1598390):

sed -E -i.bak 's/.*([0-9]{4})-[0-9]{2}-([0-9]{2})(.*)/\1\t\2\3/' infile
Run Code Online (Sandbox Code Playgroud)
  • -i.bak: 就地处理文件,将原始文件备份到 infile.bak

sed 命令分解:

  • s:断言执行替换;
  • /: 开始模式
  • [^\t]*: 匹配任意数量的任意字符,不匹配\t
  • \t: 匹配一个\t字符
  • \(: 开始第一个捕获组
  • [^-]*: 匹配任意数量的任意字符,不匹配-
  • \): 停止第一个捕获组
  • -: 匹配一个-字符
  • [0-9]: 匹配任何数字
  • [0-9]: 匹配任何数字
  • -: 匹配一个-字符
  • [0-9]: 匹配任何数字
  • \(: 启动第二个捕获组
  • [0-9]: 匹配任何数字
  • \): 停止第二个捕获组
  • [^\t]*: 匹配任意数量的任意字符,不匹配\t
  • \t: 匹配一个\t字符
  • \(: 启动第三个捕获组
  • [^\t]*: 匹配任意数量的任意字符,不匹配\t
  • \): 停止第三个捕获组
  • /: 停止模式/开始替换字符串
  • \1: 反向引用替换为第一个捕获组
  • \2: 反向引用替换为第二个捕获组
  • \3: 反向引用替换为第三个捕获组
  • /: 停止替换字符串/启动修饰符

示例文件的输出:

user@debian ~/tmp % cat infile 
a   1972-01-01  17.0265761797993
b   1972-01-02  17.200476457399
c   1972-01-03  17.2926436045271
d   1972-01-04  17.3900277599829
e   1972-01-05  17.5987080931028
f   1972-01-06  17.6334881486229
g   1972-01-07  17.7030482596626
user@debian ~/tmp % sed 's/[^\t]*\t\([^-]*\)-[0-9][0-9]-[0-9]\([0-9]\)[^\t]*\t\([^\t]*\)/\1\t\2\t\3/' infile
1972    1   17.0265761797993
1972    2   17.200476457399
1972    3   17.2926436045271
1972    4   17.3900277599829
1972    5   17.5987080931028
1972    6   17.6334881486229
1972    7   17.7030482596626
Run Code Online (Sandbox Code Playgroud)