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