列更改会使列空白而不是更改

时间:2018-02-19 08:26:36

标签: linux bash awk

我有一个制表符分隔文件,我需要使用awk更改两列。我目前使用的代码删除了我实际打算更改的所有列,并将它们留空,并将其余部分粘贴到原样。

while IFS=$'\t' read -r line ; do
some code.. (to get the value of $some_var and $another_var)
echo "$line" | awk -v var1="$some_var" -v var2="$another_var" -F $'\t' 'BEGIN {OFS = FS} { $1=$var1 } ; {if($2!="") $2=$var2 }; { print }' >> file.tsv
done < text.tsv

File content:
A    B         D
1         3    4

Intended output
H    I         D
6         3    4

Output I get:
               D
          3    4

我真正想要做的是,我有一个包含很多行的tsv文件,我必须在其中修改2列。在下面的示例(格式为%Y%m%d的日期)中,我想更改ColAColB值,其中ColA应获取ColC的值,ColB应等于(原始)ColAColB + ColC之间的持续时间。这意味着,在下面第一行中,ColAColB之间的持续时间为814天。现在我计算ColC日期后的814天,即date -d"20160201 + 814 days" +%Y%m%d。我得到20180425。这个值我应放在ColB中。所以我在while循环中执行所有这些计算,然后使用awk用值替换列。它有效,但它真的很慢,因为我必须处理多达500万条记录。

Input file
ColA        ColB        ColC
20151207    20180228    20160201
20170616    20180630    20170612

Expected output
ColA        ColB        ColC
20160201    20180425    20160201
20170612    20180626    20170612

1 个答案:

答案 0 :(得分:1)

import React from 'react'; import ReactDOM from 'react-dom'; import { BrowserRouter as Router, Route, Link } from 'react-router-dom'; import App from './components/App'; import Signin from './components/Signin'; import Signup from './components/Signup'; ReactDOM.render( <Router path="/"> <Route path="/app" component={App} /> <Route path="/signup" component={Signup} /> <Route path="/signin" component={Signin} /> </Router>, document.getElementById('root') ); 中的变量以其名称引用。您使用美元符号(awk)来引用awk程序中的字段,后跟您想要的字段编号。因此$引用第二个字段和$2引用字段$var当且仅当var是整数时,在任何其他情况下var将为空字符串。

基本上,你的代码很好。所有需要做的就是仅$var替换$var1var1替换var2。我希望这会有所帮助。

while IFS=$'\t' read -r line ; do 
  some code.. (to get the value of $some_var and $another_var)
  echo "$line" \
    | awk -v var1="$some_var" -v var2="$another_var" -F $'\t' \
         'BEGIN {OFS = FS}
          { $1=var1 }
          {if($2!="") $2=var2 }
          { print }' >> file.tsv
done < text.tsv

更新后,我相信以下awk脚本应该替换你的while循环:

awk -F $'\t' 'BEGIN {OFS = FS}
     (NR==1){print; next}
     ($2!=""){
       t1=mktime(substr($1,1,4)" "substr($1,5,2)" "substr($1,7,2)" 00 00 00");
       t2=mktime(substr($2,1,4)" "substr($2,5,2)" "substr($2,7,2)" 00 00 00");
       t3=mktime(substr($3,1,4)" "substr($3,5,2)" "substr($3,7,2)" 00 00 00");
       dt=t2-t1
       $2=strftime("%Y%m%d",t3 + dt)
     }
     {  $1=$3
       print
     }' text.tsv

我们的想法是,我们将所有日期替换为从给定时期开始的整数秒(这是通过mktime完成的,"YYYY MM DD HH MM SS [DST]"接受strftime形式的字符串,然后将其转换回来 Register() { let newUser = new User(this.registerForm.value, newUser.city =this.cityid, newUser.regionId = this.regionid, newUser.country_id = this.countryid, newUser.roleId = this.roleid, ); this.ws.createUser(newUser).subscribe( ); } export class User { password: string; roleId: string; firstName: string; . . . }