【问题标题】:Awk command to perform action on lines excluding 1st and lastawk 命令对除第一行和最后一行之外的行执行操作
【发布时间】:2019-07-30 19:55:16
【问题描述】:

我在特定目录中有多个 csv 格式的 MS excel 文件。 我想更新 csv 文件所有行中某一特定列的值。

此外,该操作不应在第一行和最后一行操作。 到目前为止,我已经为一行提出了以下代码:

awk -F, 'NR>2{$2=300;}1' OFS=, test.csv

但我在排除最后一行时遇到了困难。 另外,我需要对目录中的所有文件执行相同的操作。

到目前为止,尝试了以下但无法成功使用 awk 替换该字符串值。 1)

2)

【问题讨论】:

    标签: unix awk


    【解决方案1】:

    这可能会:

    awk -F, 't{print t} {a=t=$0} NR>1{$2=300;t=$0} END {print a}' OFS=, test.csv
    

    【讨论】:

    • 我正在尝试使用以下内容,但出现错误:awk -F, 't{print t} {a=t=$0} NR>1{$3='ops_dat';t=$0} END {print a}' OFS=, test1.csv "-sh: dbms=TD::instance=idw-prod: 没有这样的文件或目录"
    • @user3901666 由于awk被单引号包裹,你不能在awk中使用单引号,所以这将失败$3='ops_da...。谷歌搜索如何在awk 搜索中使用单引号。
    【解决方案2】:
    $ cat file
    1,a,b
    2,c,d
    3,e,f
    
    $ awk 'BEGIN{FS=OFS=","} NR>1{print (NR>2 ? chgd : orig)} {orig=$0; $2=300; chgd=$0} END{print orig}' file
    1,a,b
    2,300,d
    3,e,f
    

    【讨论】:

    • 我正在尝试使用以下内容,但出现错误:awk -F, 't{print t} {a=t=$0} NR>1{$3='ops_dat';t=$0} END {print a}' OFS=, test1.csv "-sh: dbms=TD::instance=idw-prod: 没有这样的文件或目录"
    • 您应该向建议该脚本的人询问您在尝试执行它时遇到的任何错误。
    • 是的,我做到了。我也尝试了您的脚本,但这也不适用于我提到的情况。
    • 你问了一个问题,我回答了。如果您有新问题,请随时发布
    • 谢谢埃德。是的,我会的。
    【解决方案3】:

    您可以通过两次读取文件来稍微简化脚本:

    awk 'BEGIN{FS=OFS=","} NR==FNR {c=NR;next} !(FNR==1||FNR==c){$2=200} 1' file file
    

    这仅使用NR==FNR 部分来计算行数,为您提供一个简单的表达式来确定是否更新相关字段。

    如果您有可用的 GNU awk,则可以通过不为每一行重新分配 c 变量来节省一些 CPU 周期,使用如下:

    gawk 'BEGIN{FS=OFS=","} ENDFILE {c=FNR} NR==FNR{next} !(FNR==1||FNR==c){$2=200} 1' file file
    

    这仍然读取文件两次,但仅在读取每个文件后分配c

    如果您愿意,您可以在非 GNU awk 中使用 NR>FNR && FNR==1 模拟 ENDFILE 条件(如果您只有两个文件),然后设置 c=NR-1。它不会表现得那么好。

    我没有测试这两者之间的速度差异,但我怀疑它可以忽略不计,除非文件真的非常大。

    【讨论】:

    • 好主意。如果您的文件很大,或者更有效:awk -v c="$(wc -l < file)" 'BEGIN{FS=OFS=","} (NR>1) && (NR<c){$2=200} 1' file(切换到正逻辑只是我的偏好,wc 会提高性能)。 `
    • @ghoti 我尝试在下面使用:---- awk -F, 't{print t} {a=t=$0} NR>2{$3='ops_dat\';t=$0} END {print a}' OFS=, test1.csv ----- 仍然报错。
    • @user3901666,对于该解决方案,也许您应该询问 Jotne。如果您遇到错误,也许您可​​以更新您的问题以包括尝试的详细信息以及错误。问题中的格式化比 cmets 中的要好得多。哦,注意你的报价。从这里看起来好像您正试图在单引号字符串中包含单引号,这当然行不通。
    • 是的,我也搜索了谷歌,但我找不到任何明确的解决方案。
    • 根据您的更新,正如我所建议的那样——您应该为单引号脚本中的赋值切换到双引号。
    【解决方案4】:

    谢谢大家, 我必须让它工作。下面是命令:

    awk -v sq="" -F, 't{print t} {a=t=$0} NR>2{$3=sq"ops_data"sq;t=$0} END {print a}' OFS= , test1.csv

    【讨论】:

      猜你喜欢
      • 2019-11-04
      • 2011-01-16
      • 1970-01-01
      • 2012-07-18
      • 1970-01-01
      • 2020-04-14
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多