我不确定如何表达这个问题,因为大多数答案都是关于\r\n
从文件中删除的。
我有一个独特的问题,压缩文件是随机编号的,为了将它们与数据库记录正确关联,我需要列出文件内容并检查它们。
我正在使用这个解决方案 “在 bash 脚本中,如何逐行捕获标准输出”
这是一个很好的开始。
一些内容的名称带有空格,我找到了这个解决方案: 如何将第三列打印到最后一列?
我在尝试更新数据库记录时发现,该记录^M
被插入到awk
管道的结果中,但仅用于NF
列。
不知道如何解决这个特定的故障。我看不到^M
插入的位置,或者如何从最后一列中删除它。
我的代码
如果我剥离,这条线可以正常工作^M
filename="$(echo "$line" | awk '{if ($3 ~ /^M$/) {sub(/^M$/,"", $3)} printf $3; printf ""}')"
此行失败:
text="$(echo "$line" | awk '{for(i=6;i<NF+1;i++) {if ($i ~ /^M$/) {sub(/^M$/,"", $i)} } printf "%s ", $i; printf ""}')"
简化版失败:
text="$(echo "$line" | awk '{for(i=6;i<NF+1;i++) sub(/^M$/,"", $i) printf "%s ", $i; printf ""}')"
在vim
/中
使用 Usingvi
^M
创建没有效果。ctrl-V + <return key>
\r\n
我正在使用cygwin
,并且已经使用了很长时间,并且我*nix
编写了其他运行良好的脚本。我发现由于某种原因,这个特定的运行awk
正在添加^M
到输出中。
我发现这个问题有一个类似的问题,但是我vim
从一开始就创建了我的脚本,所以没有涉及基于 Windows 的编辑器。
如果我将该 windows 文件夹挂载为 samba 共享并从 linux 运行脚本,它会产生不带 a 的输出^M
,所以此时我想知道这是一个错误还是其他什么。这真的很奇怪。
更新 我在 sub() 中使用 REGEX 导致字符串返回空,所以我没有正确理解如何清除 CRLF。
NF+1 是试图找出我在此之前使用 i<=NF 引入 CRLF 的结果。
通过
awk
包括 GNUawk
和mawk
busybox的一些实现awk
(在基于 Linux 的系统上常见的 3 个实现,awk
我相信 Cygwin 默认是 GNU),RS
输入记录分隔符可以是正则表达式(而不是 POSIX 中的单个字符) .在这些中,您可以执行以下操作:
处理这些文件,或者:
能够处理带有
\n
分隔符或\r\n
分隔符的两个文件。一些 MS-DOS 文件也倾向于最后一行不分隔,但
awk
也会在输出时修复它,因为它会在打印时将输出记录分隔符(ORS
保留在此处)附加到所有记录。\n
就默认字段拆分而言
awk
,您还会发现实现之间存在差异。POSIX 说它应该按照空白序列进行拆分,删除前导和尾随的序列。空白的概念取决于区域设置,并且至少包括 SPC 和 TAB。您会发现许多awk
实现仅将其限制为 SPC 和 TAB 而与语言环境无关,许多实现还添加了 NL(仅当记录分隔符不是换行符时才相关)。busybox
awk 包括所有 ASCII 空格,因此包括CR
,FF
,VT
. 所以在 busyboxawk
中,默认情况下字段从不包含 CR。awk
您可以通过gawk -v 'FPAT=[^[:space:]]'
将 where 字段定义为非空白序列来实现与 GNU 相同的行为。还有一些注意事项:
awk
which 是处理文本的正确工具之一。echo
任意数据printf
是格式,你不想在那里使用任意数据。printf "%s", $3
如果要打印$3
而不附加,请使用ORS
,而不是。printf $3
printf ""
是无操作的。它什么也没做。如果要打印换行符,请使用printf "\n"
orprint ""
(后者ORS
默认打印 , newline)。awk
不识别^M
字面,它将其识别为 CRLF 模式\r\n
,因此您sub()
可以直接使用 CR 字符表示,如下所示。此外,您不必检查该字段是否包含字符并进行替换。如果没有找到提到的模式,替换函数根本不做任何事情。因此,您只需要以下内容即可仅替换最后一列的 CR。如果有多个列需要更换,请切换
$NF
到所需的相应列。如果您对文件末尾的所有列循环执行此操作,只需执行
文件也只能有最大
NF
列并且$NF
是最后一列值。将循环更改为运行直到NF
访问最后一列值。