awk - 将列中大于 17 位的数字替换为 -

awk - 将列中大于 17 位的数字替换为 -

我有一个 CSV 文件,其中包含 UTC 时间戳值,我需要将其替换为-.同一列中可能有多个时间戳,您能告诉我该怎么做吗?

例如,这是 CSV 文件中的一列:

+1234|2|12|1|1|1537820114232192380|0  +1234|2|12|1|1|1537820113262689150|0

输出应如下所示:

+1234|2|12|1|1|-|0  +1234|2|12|1|1|-|0

答案1

由于它位于 a 内部file,因此使用 sed 速度更快:

sed -i 's/[0-9]\{18,\}/-/g' file

了解该-i选项将更改您的文件。如果您想在提交之前查看它的作用,请删除-i.

请注意,在 BSD 中,-i应该有一个参数,因此使用:-i ''

awk 也可以做到:

<file awk '{gsub("[0-9]{18,}", "-")}1'  >newfile

答案2

您可以awk按如下方式使用:

echo "+1234|2|12|1|1|1537820114232192380|0  +1234|2|12|1|1|1537820113262689150|0" | awk '{gsub("[0-9]{18,}", "-")}1'
  +1234|2|12|1|1|-|0  +1234|2|12|1|1|-|0

您可以sed按如下方式使用:

  echo "+1234|2|12|1|1|1537820114232192380|0  +1234|2|12|1|1|1537820113262689150|0" | sed -r 's/[0-9]{18,}/-/g'
  +1234|2|12|1|1|-|0  +1234|2|12|1|1|-|0

答案3

如果出于某种原因,您想避免使用正则表达式或 awk 之外的工具,您可以选择使用awk 条件语句

echo "+1234|2|12|1|1|1537820114232192380|0  +1234|2|12|1|1|1537820113262689150|0" | awk -F'|' 'OFS="|" { for (i = 1; i <= NF; i++) { if (length($i) > 17) { $i = "-"} } print; }'

+1234|2|12|1|1|-|0  +1234|2|12|1|1|-|0

解释:

-F'|'                            # Set input field-separator to bar
'OFS="|"                         # Set output field-separator to bar
{ for (i = 1; i <= NF; i++) {    # Loop through the fields
if (length($i) > 17) { $i = "-"} # Set a field with length over 17 to "-"
} print; }'                      # Print output of all fields after this process

答案4

我会使用 awk (并使用 sed 用换行符替换尾随的 ORS)来使用此变体,它会检查字符串长度为 17 个字符或以上。

awk -vRS='[|\n]' -vORS='|' 'length($0)>=17{$0="-"}1' | sed 's/|$/\n/'

仅过滤掉数字超过 17 位数字时,执行以下操作:

awk -vRS='[|\n]' -vORS='|' 'log($0)/log(2)>=17{$0="-"}1' | sed 's/|$/\n/'

还有一些技巧可以完全避免 sed 并使用单个 awk 进程,如下所示:https://stackoverflow.com/questions/34684958/make-the-record-seperator-in-awk-not-apply-after-the-last-record

这样我们就可以使用awk的记录分割和过滤功能,并且我们可以对过滤器有更精确的控制,而不是正则表达式。

验证测试:

$ awk -vRS='[|\n]' -vORS='|' 'length($0)>=17{$0="-"}1' <<< '+1234|2|12|1|1|1537820114232192380|0  +1234|2|12|1|1|1537820113262689150|0' | sed 's/|$/\n/'
+1234|2|12|1|1|-|0  +1234|2|12|1|1|-|0

$ awk -vRS='[|\n]' -vORS='|' 'log($0)/log(2)>=17{$0="-"}1' <<< '+1234|2|12|1|1|1537820114232192380|0  +1234|2|12|1|1|1537820113262689150|0' | sed 's/|$/\n/'
+1234|2|12|1|1|-|0  +1234|2|12|1|1|-|0

相关内容