:
是的另一个名称true
。两者都是bash中的shell内置程序,但是没有/bin/:
,只有一个/bin/true
。输出重定向会导致Shell到open(2)
文件O_CREAT|O_TRUNC
。如果未写入任何内容,则它将保持零长度。
将这两部分放在一起,:> file
是截断文件的相当普遍的习惯用法。不过,大多数人会尝试通过书写来使它看起来不那么怪异: >file
。
既然您在第二行的评论中提问,我将把我的评论变成答案。(即使您没有在问题中问这个。)
第二行是一个循环,将从中读取行otherfile
到一些命名变量中。循环主体使用分隔符而不是之前的空白echo
来打印它们;
。 file
在每次迭代中关闭并重新打开(用于追加),因为重定向位于循环内部。使用while ...;do read -r ...;done <otherfile >file
会减少麻烦,并且避免首先截断文件。read -r
不\
作为逃脱角色进食。
bash中的文本处理非常慢。其中一部分是不可避免的:read
必须一次传送一个字节(read(2)
每个字节一次系统调用),以免超出行尾。最好使用正确的工具来完成这项工作:
awk -vOFS=';' '{ print $1, $2, $4, $5, $3 }' -- otherfile >file
--
表示如果您的脚本otherfile
被命名为愚蠢的像,它不会中断--version
。
将输出字段分隔符设置为;
意味着您可以将多个字段作为args传递进行打印。Shell read
将带有空格的整个行的其余部分分配给最后一个变量,但是没有办法告诉awk只拆分为5。如果这很重要,则也许继续使用bash循环,因为它在awk中很不方便。Perl使这个过程变得容易,因为它split
可以使用max-fields arg,但是它的启动要比awk慢得多。
实际上,事实并非如此,只是编写一个难看的正则表达式。要获得其余内容而不是$5
awk,遍历字段仍然会丢失其原始空格。我的第一个可行的想法是用gensub
在$0
(整行)删除第4场(即非空间其次是空间),让一切:
awk -vOFS=';' '{ tail = gensub("[[:space:]]*([^[:space:]]+[[:space:]]+){4}", "", 1); print $1, $2, $4, tail, $3 }' -- otherfile >file
第一次尝试时我做对了,但是我对此印象深刻,这一事实说明了该awk代码的可读性。>。<
请注意,它与print
以前一样,但是用tail
代替$5
。
echo 'A B c DD e f g f' |
awk -vOFS=\; '{ tail = gensub("[[:space:]]*([^[:space:]]+[[:space:]]+){4}", "", 1);
print $1, $2, $4, tail, $3 }'
A;B;DD;e f g f;c
如果我可以复制/粘贴文字并将其显示在输出中,这会给人留下深刻的印象。用^ Q在bash中键入一。ctrl-Q表示将下一个按键作为文字字符引用,因为bash的emacs样式的行编辑与此实际emacs相同。
http://mywiki.wooledge.org/BashFAQ提供了一些有用的脚本知识,无论您在脚本中抛出什么数据或文件名,它们都不会中断。
:>
是,不是单个运算符。如果您改为阅读它,可能会更容易理解: > file
。