cat
cat(1) is short for “concatenate”. It was originally designed to merge text files into one, but can be used for many other purposes.
cat
命令最初是用于合并多个文本文件用的。如
$ cat file1 file2 file3 > bigfile
现如今很多人使用它配合 more / less
命令来显示文件内容。
$ cat file | more
或者用来复制文件,下面的命令将 bash 复制到 home 目录下,并命名为 mybash
$ cat /bin/bash > ~/mybash
由于 cat
大量使用标准输入和标准输出,因此非常适合在 shell 脚本或其他复杂命令的一部分中使用。
Here Documents1
COMMAND <<InputComesFromHERE
...
...
...
InputComesFromHERE
The cat <<EOF
syntax is very useful when working with multi-line text in Bash, eg. when assigning multi-line string to a shell variable, file or a pipe.
Examples of cat <<EOF
syntax usage in Bash
<<here
告诉 shell 你将输入一个多行的字符串直到标签 here
出现为止。标签被称为 "here tag"
。
here tag
命名没有特定规则,通常人们会命名为 EOF
或者 STOP
。
Assign multi-line string to a shell variable
$ var=$(cat <<EOF
hello world
EOF
)
echo -e $var
Pass multi-line string to a file in Bash
$ cat <<EOF > print.sh
#!bin/bash
echo \$PWD
echo $PWD
EOF
The print.sh
file now contains:
#!/bin/bash
echo $PWD
echo /home/[your username]
Pass multi-line string to a pipe in Bash
$ cat <<EOF | grep 'b' | tee b.txt
foo
bar
baz
EOF
其他
- 某些场景下不希望变量在字符串中展开,不希望转义,则将
here tag
加上引号即可。
cat <<'EOF'
$PWD
EOF
- 某些场景不希望输出文本中的前导
tabs
,则可以在here tag
前加上-
,<<-heretags
。 - 代码注释,triky 用法。这样可以避免每次采用
#
注释代码块后恢复的麻烦。: <<'here tag'
,这被称为匿名的 here document。
: <<'COMMENTBLOCK'
echo "This line will not echo." # commented-out code block
COMMENTBLOCK
和 echo 的对比
对空格的处理
var="12 3" # two space
echo $var
# you will get "12 3" # just one space
echo 输出的时候连续空格会被减少到 1 个输出,这无法满足我们的需求。使用 here document
则可以避免找个问题。
var="12 3"
cat <<EOF
We need '\$var" to be expanded and look like this: '$var"
EOF
# to get: We need '$var" to be expanded and look like this: '12 3"
- echo 中
"" ''
的使用过于复杂,不好处理,容易出错。 - echo 有输出字符数限制,
getconf ARG_MAX
- echo 不够美观,在输出大量多行字符的时候,
echo
往往显得不够美观。
Here Strings
这个其实可以看成 Here Document
的缩减版。
It consists of nothing more than COMMAND <<< $WORD, where $WORD is expanded and fed to the stdin of COMMAND.
# Instead of:
if echo "$VAR" | grep -q txt # if [[ $VAR = *txt* ]]
# etc.
# Try:
if grep -q "txt" <<< "$VAR"
then # ^^^
echo "$VAR contains the substring sequence \"txt\""
fi
https://tldp.org/LDP/abs/html/here-docs.html ↩︎