Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/bash/18.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Bash 根据文件中行的可变长度添加和删除列的脚本_Bash_Shell_Awk_Cut - Fatal编程技术网

Bash 根据文件中行的可变长度添加和删除列的脚本

Bash 根据文件中行的可变长度添加和删除列的脚本,bash,shell,awk,cut,Bash,Shell,Awk,Cut,我在karan.csv文件中有n条记录,格式如下: A=9607738162|B=9607562681|C=20200513191434|D=|F=959852599|G=MT|H=4012|I=4012|J=9607562681|K=947100410| A=960299773008|B=9607793008|C=20200513191327|D=|E=ST|F=959852599|G=MO|H=2001|I=2001|J=9607793008|K=947100180| A=960770453

我在karan.csv文件中有n条记录,格式如下:

A=9607738162|B=9607562681|C=20200513191434|D=|F=959852599|G=MT|H=4012|I=4012|J=9607562681|K=947100410|
A=960299773008|B=9607793008|C=20200513191327|D=|E=ST|F=959852599|G=MO|H=2001|I=2001|J=9607793008|K=947100180|
A=9607704530|B=9607839496|C=20200513191730|D=|F=959852599|G=MT|I=5012|J=9607839496|K=|
现在如果我们注意到,列的数量分别是:10、11和9。此计数在文件中是随机的,但是列数将保持不变

现在,我想创建一个脚本,该脚本将从该列中删除$5,包括分隔符,如果一行中有11列,那么它看起来与包含10列的行完全相同

A=9607738162|B=9607562681|C=20200513191434|D=|F=959852599|G=MT|H=4012|I=4012|J=9607562681|K=947100410|
在7美元中加上H=|,其中列计数为9

A=9607704530|B=9607839496|C=20200513191730|D=|F=959852599|G=MT|H=|I=5012|J=9607839496|K=|
现在我编写了以下代码来实现它:

for text in $(cat /tmp/karan.csv);do
  count=`awk -F"|" '{print NF-1}' $text`
  if [ $count == 9 ]
  then
  awk  'BEGIN{FS=OFS="|"}{$7="|H"}1' $text >> /tmp/karantest2.csv
  elif [ $count == 10 ]
  then
  echo $text >> /tmp/karantest2.csv
  else
  awk -F"|" '{print $1,$2,$3,$4,$6,$7,$8,$9,$10,$11}' $text >> /tmp/karantest2.csv
  fi
  done
但在调试之后,我意识到脚本在以下情况下没有进展:

count=`awk -F"|" '{print NF-1}' $text`
关于这件事,有谁能请我谈谈吗


关于sed解决方案,它首先在包含9列的行中插入H=|,然后在包含11列的行中删除第7列:

sed-E'/^[^\\\\]+\\\\{9}$/s/[^\\\\\]+\\\\\{6}/\1H=\\\\\\;//^[^\\\\]+\\\\\{11}$/s/[^\\\\\\\\]+\\\\\\{4}[^\\\\\\\]+\\\\\\\/\1/inputfile 如果需要兼容POSIX的命令,那么

由于-E不是POSIX,您必须转义每个,{,},+和其他特殊字符,这些字符不在这个命令中,并且取消转义\|使其成为文字; 因为\+也不是POSIX,所以需要使用更详细的\{1,\}。 以下是与POSIX兼容的命令:

sed'/^\[^ |]\{1,\}\\{9\}$/s/\\[^ |]\{1,\}\{6\}\/\1H=\\\//^\[^ |]\{1,\}\{11\}$/s/\\[^ |]\{1,\}\\{4\}\[^ |]\{1,\}/\1/'输入文件 纯awk解决方案:

awk -F'|' '

BEGIN { OFS="|" }

NF==10 { print $1, $2, $3, $4, $5, $6, "H=", $7, $8, $9, $10 }
NF==11 { print $0 }
NF==12 { print $1, $2, $3, $4, $6, $7, $8, $9, $10, $11, $12 }

' karen.csv
提供的样本输入的输出为:

A=9607738162|B=9607562681|C=20200513191434|D=|F=959852599|G=MT|H=4012|I=4012|J=9607562681|K=947100410|
A=960299773008|B=9607793008|C=20200513191327|D=|F=959852599|G=MO|H=2001|I=2001|J=9607793008|K=947100180|
A=9607704530|B=9607839496|C=20200513191730|D=|F=959852599|G=MT|H=|I=5012|J=9607839496|K=|

变量文本在每次迭代中保存CSV文件的一行。然后告诉awk,这一行是要处理的文件的名称。当然,没有一个文件名。我原以为awk会发出错误消息,但我通过调用awk不存在的文件来尝试,事实上,它没有抱怨,而是在stdin上等待输入被处理。我同意@user1934428。但是有没有一种方法可以将awk用于变量,比如“$text”,而不是file.-E在solaris机器上是非法选项。当我尝试使用-r时,我也会遇到同样的错误。我不习惯使用sed命令,所以我只是复制并粘贴了您的命令,当然更改了文件名。它只是按原样打印文件,没有任何修改,也没有删除或添加文件中的任何列。基于我可以复制的内容,我提供的命令似乎不符合POXIS,但我不知道为什么。今天晚些时候我会看一看。@KaranKohli,发现。\+不是POSIX,所以您必须使用\{1,\}。@KaranKohli。不客气。请投票表决答案。