如何使用bash将行的最后[0-9]{1,9}单元格值移动到最后一行(.csv)
示例.csv:如何使用bash将行的最后[0-9]{1,9}单元格值移动到最后一行(.csv),bash,macos,csv,sed,sh,Bash,Macos,Csv,Sed,Sh,示例.csv: "something","31","null","null","null","null", "something","something","something","142","null","null", "something","something","24","null","null","null", 我希望得到这样的结果: "something","null","null","null","null","31", "something","something","some
"something","31","null","null","null","null",
"something","something","something","142","null","null",
"something","something","24","null","null","null",
我希望得到这样的结果:
"something","null","null","null","null","31",
"something","something","something","null","null","142",
"something","something","null","null","null","24",
如何使用bash脚本将最后[0-9]{1,9}个数值移动到最后一个单元格中(如果后面的单元格中只有空值)
我试着用sed来做,但没有成功。这个简短的awk脚本适用于给定的示例:
awk -F',' -v OFS=',' -v pat='^"[0-9]+"$' '{
for(i=NF;i>0;i--)if($i~ pat ){$NF=$i FS;$i="\x98";break}
sub("\x98,","")
}7' file
简要说明:
这是一个有趣的问题
变量存储我们要移到末尾的正则表达式模式pat
- 对于每一行,我们从末尾开始循环并检查模式,以便确保找到最后一个匹配的列
- 如果我们找到了col,我们将最后一个字段设置为带有逗号的匹配列。(我注意到在每行的末尾总是有一个空字段)。我们将col的值设置为一个不可见的值
,以便以后可以轻松删除\x98
- 最后,我们通过
sub()
此短awk脚本适用于给定示例:
awk -F',' -v OFS=',' -v pat='^"[0-9]+"$' '{
for(i=NF;i>0;i--)if($i~ pat ){$NF=$i FS;$i="\x98";break}
sub("\x98,","")
}7' file
简要说明:
这是一个有趣的问题
变量存储我们要移到末尾的正则表达式模式pat
- 对于每一行,我们从末尾开始循环并检查模式,以便确保找到最后一个匹配的列
- 如果我们找到了col,我们将最后一个字段设置为带有逗号的匹配列。(我注意到在每行的末尾总是有一个空字段)。我们将col的值设置为一个不可见的值
,以便以后可以轻松删除\x98
- 最后,我们通过
sub()
下面是我在bash中的变体,并给出了解释
raw=( $(cat file) ) # load data to raw array
for item in "${raw[@]}"; { # loop through raw data
search=${item//[!0-9]/} # this will give only digits
# if match found remove it from string by change ,"123", to a comma and paste to the end
[[ $search ]] && item="${item//,\"$search\",/,}\"$search\","
echo $item # print result
}
下面是我在bash中的变体,并给出了解释
raw=( $(cat file) ) # load data to raw array
for item in "${raw[@]}"; { # loop through raw data
search=${item//[!0-9]/} # this will give only digits
# if match found remove it from string by change ,"123", to a comma and paste to the end
[[ $search ]] && item="${item//,\"$search\",/,}\"$search\","
echo $item # print result
}
字段值包含分隔符(
,
)的可能性有多大?如果可能性不大,awk
将是你最好的选择。遗憾的是,awk
并不能更好地支持CSV(比如引用的字段)。(编辑:看起来您可以使用-F',“
作为分隔符?)还可以查看Trysed-i.bak-E的/^(.*)(“[0-9]+”,)(.*,”,“,”,)$/\1\3\2/”文件
@WiktorStribiżew这并不保证最后的“[0-9]+”已被移动。@Kent它确实被授予了输入完全是OP格式的权限。字段值包含分隔符(,
)的可能性有多大?如果可能性不大,awk
将是你最好的选择。遗憾的是,awk
并不能更好地支持CSV(比如引用的字段)。(编辑:看起来您可以使用-F'”、“
作为分隔符?)也可以看看Trysed-i.bak-E的/^(.*)(“[0-9]+”、(.*”、“null”、)$/\1\3\2/”文件
@WiktorStribiżew这并不保证最后一个“[0-9]+”已被移动。@Kent它确实允许输入是精确的OP格式。@ChristianFröhlich欢迎您。在这里,一个人通过向上投票并接受答案来表示感谢。这可能是因为,如果值是空的“”而不是“null”,那么它将不起作用吗?@ChristianFröhlich也应该起作用,如果空字符串像其他字段一样用双引号括起来。它工作得很好!你能给我一个提示吗,如果我只想移动最后x列中的数字,我需要修改什么部分(前面更多的是我不想移动的id和其他数字)。还是我应该为它提出一个新问题?@ChristianFröhlich很高兴听到这一点。对于您的新需求,您可以尝试扩展if($i~pat)
->if($i~pat&&i>NF-x)
,其中x
是您想要的范围。首先用一个固定的x
和相应的示例进行尝试。祝你好运。@ChristianFröhlich欢迎你。在这里,一个人通过向上投票并接受答案来表示感谢。这可能是因为,如果值是空的“”而不是“null”,那么它将不起作用吗?@ChristianFröhlich也应该起作用,如果空字符串像其他字段一样用双引号括起来。它工作得很好!你能给我一个提示吗,如果我只想移动最后x列中的数字,我需要修改什么部分(前面更多的是我不想移动的id和其他数字)。还是我应该为它提出一个新问题?@ChristianFröhlich很高兴听到这一点。对于您的新需求,您可以尝试扩展if($i~pat)
->if($i~pat&&i>NF-x)
,其中x
是您想要的范围。首先用一个固定的x
和相应的示例进行尝试。祝你好运。谢谢,它可以工作,因为我看到脚本正在工作,但几分钟后我需要取消它。也许它不适用于更大的csv文件。谢谢,它可以工作,因为我看到脚本正在工作,但几分钟后我需要取消它。也许它不适用于更大的csv文件。