mirror of
https://github.com/LCTT/TranslateProject.git
synced 2024-12-23 21:20:42 +08:00
hankchow translated
This commit is contained in:
parent
fb99e37210
commit
b0aad8e5b3
@ -1,154 +0,0 @@
|
||||
[#]: collector: (lujun9972)
|
||||
[#]: translator: (HankChow)
|
||||
[#]: reviewer: ( )
|
||||
[#]: publisher: ( )
|
||||
[#]: url: ( )
|
||||
[#]: subject: (Understanding Angle Brackets in Bash)
|
||||
[#]: via: (https://www.linux.com/blog/learn/2019/1/understanding-angle-brackets-bash)
|
||||
[#]: author: (Paul Brown https://www.linux.com/users/bro66)
|
||||
|
||||
Understanding Angle Brackets in Bash
|
||||
======
|
||||
|
||||
![](https://www.linux.com/sites/lcom/files/styles/rendered_file/public/architecture-1839450_1920.jpg?itok=ra6XonD3)
|
||||
|
||||
[Bash][1] provides many important built-in commands, like `ls`, `cd`, and `mv`, as well as regular tools such as `grep`, `awk,` and `sed`. But, it is equally important to know the punctuation marks -- [the glue in the shape of dots][2], commas, brackets. and quotes -- that allow you to transform and push data from one place to another. Take angle brackets (`< >`), for example.
|
||||
|
||||
### Pushing Around
|
||||
|
||||
If you are familiar with other programming and scripting languages, you may have used `<` and `>` as logical operators to check in a condition whether one value is larger or smaller than another. If you have ever written HTML, you have used angle brackets to enclose tags.
|
||||
|
||||
In shell scripting, you can also use brackets to push data from place to place, for example, to a file:
|
||||
|
||||
```
|
||||
ls > dir_content.txt
|
||||
```
|
||||
|
||||
In this example, instead of showing the contents of the directory on the command line, `>` tells the shell to copy it into a file called _dir_content.txt_. If _dir_content.txt_ doesn't exist, Bash will create it for you, but if _dir_content.txt_ already exists and is not empty, you will overwrite whatever it contained, so be careful!
|
||||
|
||||
You can avoid overwriting existing content by tacking the new stuff onto the end of the old stuff. For that you use `>>` (instead of `>`):
|
||||
|
||||
```
|
||||
ls $HOME > dir_content.txt; wc -l dir_content.txt >> dir_content.txt
|
||||
```
|
||||
|
||||
This line stores the list of contents of your home directory into _dir_content.txt_. You then count the number of lines in _dir_content.txt_ (which gives you the number of items in the directory) with [`wc -l`][3] and you tack that value onto the end of the file.
|
||||
|
||||
After running the command line on my machine, this is what my _dir_content.txt_ file looks like:
|
||||
|
||||
```
|
||||
Applications
|
||||
bin
|
||||
cloud
|
||||
Desktop
|
||||
Documents
|
||||
Downloads
|
||||
Games
|
||||
ISOs
|
||||
lib
|
||||
logs
|
||||
Music
|
||||
OpenSCAD
|
||||
Pictures
|
||||
Public
|
||||
Templates
|
||||
test_dir
|
||||
Videos
|
||||
17 dir_content.txt
|
||||
```
|
||||
|
||||
The mnemonic here is to look at `>` and `>>` as arrows. In fact, the arrows can point the other way, too. Say you have a file called _CBActors_ containing some names of actors and the number of films by the Coen brothers they have been in. Something like this:
|
||||
|
||||
```
|
||||
John Goodman 5
|
||||
John Turturro 3
|
||||
George Clooney 2
|
||||
Frances McDormand 6
|
||||
Steve Buscemi 5
|
||||
Jon Polito 4
|
||||
Tony Shalhoub 3
|
||||
James Gandolfini 1
|
||||
```
|
||||
|
||||
Something like
|
||||
|
||||
```
|
||||
sort < CBActors # Do this
|
||||
Frances McDormand 6 # And you get this
|
||||
George Clooney 2
|
||||
James Gandolfini 1
|
||||
John Goodman 5
|
||||
John Turturro 3
|
||||
Jon Polito 4
|
||||
Steve Buscemi 5
|
||||
Tony Shalhoub 3
|
||||
```
|
||||
|
||||
Will [sort][4] the list alphabetically. But then again, you don't need `<` here since `sort` already expects a file anyway, so `sort CBActors` will work just as well.
|
||||
|
||||
However, if you need to see who is the Coens' favorite actor, you can check with :
|
||||
|
||||
```
|
||||
while read name surname films; do echo $films $name $surname > filmsfirst.txt; done < CBActors
|
||||
```
|
||||
|
||||
Or, to make that a bit more readable:
|
||||
|
||||
```
|
||||
while read name surname films;\
|
||||
do
|
||||
echo $films $name $surname >> filmsfirst;\
|
||||
done < CBActors
|
||||
```
|
||||
|
||||
Let's break this down, shall we?
|
||||
|
||||
* the [`while ...; do ... done`][5] structure is a loop. The instructions between `do` and `done` are repeatedly executed while a condition is met, in this case...
|
||||
* ... the [`read`][6] instruction has lines to read. `read` reads from the standard input and will continue reading until there is nothing more to read...
|
||||
* ... And as standard input is fed in via `<` and comes from _CBActors_ , that means the `while` loop will loop until the last line of _CBActors_ is piped into the loop.
|
||||
* Getting back to `read` for a sec, the tool is clever enough to see that there are three distinct fields separated by spaces on each line of the file. That allows you to put the first field from each line in the `name` variable, the second in `surname` and the third in `films`. This comes in handy later, on the line that says `echo $films $name $surname >> filmsfirst;\`, allowing you to reorder the fields and push them into a file called _filmsfirst_.
|
||||
|
||||
|
||||
|
||||
At the end of all that, you have a file called _filmsfirst_ that looks like this:
|
||||
|
||||
```
|
||||
5 John Goodman
|
||||
3 John Turturro
|
||||
2 George Clooney
|
||||
6 Frances McDormand
|
||||
5 Steve Buscemi
|
||||
4 Jon Polito
|
||||
3 Tony Shalhoub
|
||||
1 James Gandolfini
|
||||
```
|
||||
|
||||
which you can now use with `sort`:
|
||||
|
||||
```
|
||||
sort -r filmsfirst
|
||||
```
|
||||
|
||||
to see who is the Coens' favorite actor. Yes, it is Frances McDormand. (The [`-r`][4] option reverses the sort, so McDormand ends up on top).
|
||||
|
||||
We'll look at more angles on this topic next time!
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
|
||||
via: https://www.linux.com/blog/learn/2019/1/understanding-angle-brackets-bash
|
||||
|
||||
作者:[Paul Brown][a]
|
||||
选题:[lujun9972][b]
|
||||
译者:[译者ID](https://github.com/译者ID)
|
||||
校对:[校对者ID](https://github.com/校对者ID)
|
||||
|
||||
本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出
|
||||
|
||||
[a]: https://www.linux.com/users/bro66
|
||||
[b]: https://github.com/lujun9972
|
||||
[1]: https://www.linux.com/blog/2019/1/bash-shell-utility-reaches-50-milestone
|
||||
[2]: https://www.linux.com/blog/learn/2019/1/linux-tools-meaning-dot
|
||||
[3]: https://linux.die.net/man/1/wc
|
||||
[4]: https://linux.die.net/man/1/sort
|
||||
[5]: http://tldp.org/HOWTO/Bash-Prog-Intro-HOWTO-7.html
|
||||
[6]: https://linux.die.net/man/2/read
|
151
translated/tech/20190124 Understanding Angle Brackets in Bash.md
Normal file
151
translated/tech/20190124 Understanding Angle Brackets in Bash.md
Normal file
@ -0,0 +1,151 @@
|
||||
[#]: collector: (lujun9972)
|
||||
[#]: translator: (HankChow)
|
||||
[#]: reviewer: ( )
|
||||
[#]: publisher: ( )
|
||||
[#]: url: ( )
|
||||
[#]: subject: (Understanding Angle Brackets in Bash)
|
||||
[#]: via: (https://www.linux.com/blog/learn/2019/1/understanding-angle-brackets-bash)
|
||||
[#]: author: (Paul Brown https://www.linux.com/users/bro66)
|
||||
|
||||
理解 Bash 中的尖括号
|
||||
======
|
||||
|
||||
![](https://www.linux.com/sites/lcom/files/styles/rendered_file/public/architecture-1839450_1920.jpg?itok=ra6XonD3)
|
||||
|
||||
[Bash][1] 内置了很多诸如 `ls`、`cd`、`mv` 这样的重要的命令,也有很多诸如 `grep`、`awk`、`sed` 这些有用的工具。但除此之外,其实 [Bash][1] 中还有很多可以[起到胶水作用][2]的标点符号,例如点号(`.`)、逗号(`,`)、括号(`<>`)、引号(`"`)之类。下面我们就来看一下可以用来进行数据转换和转移的尖括号()。
|
||||
|
||||
### 转移数据
|
||||
|
||||
如果你对其它编程语言有所了解,你会知道尖括号 `<` 和 `>` 一般是作为逻辑运算符,用来比较两个值之间的大小关系。如果你还编写 HTML,尖括号作为各种标签的一部分,就更不会让你感到陌生了。
|
||||
|
||||
在 shell 脚本语言中,尖括号可以将数据从一个地方转移到另一个地方。例如可以这样把数据存放到一个文件当中:
|
||||
|
||||
```
|
||||
ls > dir_content.txt
|
||||
```
|
||||
|
||||
在上面的例子中,`>` 符号让 shell 将 `ls` 命令的输出结果写入到 `dir_content.txt` 里,而不是直接显示在命令行中。需要注意的是,如果 `dir_content.txt` 这个文件不存在,Bash 会为你创建出来;但是如果 `dir_content.txt` 是一个已有得非空文件,它的内容就会被覆盖掉。所以执行类似的操作之前务必谨慎。
|
||||
|
||||
你也可以不使用 `>` 而使用 `>>`,这样就可以把新的数据追加到文件的末端而不会覆盖掉文件中已有的数据了。例如:
|
||||
|
||||
```
|
||||
ls $HOME > dir_content.txt; wc -l dir_content.txt >> dir_content.txt
|
||||
```
|
||||
|
||||
在这串命令里,首先将 home 目录的内容写入到 `dir_content.txt` 文件中,然后使用 `wc -l` 计算出 `dir_content.txt` 文件的行数(也就是 home 目录中的文件数)并追加到 `dir_content.txt` 的末尾。
|
||||
|
||||
在我的机器上执行上述命令之后,`dir_content.txt` 的内容会是以下这样:
|
||||
|
||||
```
|
||||
Applications
|
||||
bin
|
||||
cloud
|
||||
Desktop
|
||||
Documents
|
||||
Downloads
|
||||
Games
|
||||
ISOs
|
||||
lib
|
||||
logs
|
||||
Music
|
||||
OpenSCAD
|
||||
Pictures
|
||||
Public
|
||||
Templates
|
||||
test_dir
|
||||
Videos
|
||||
17 dir_content.txt
|
||||
```
|
||||
|
||||
你可以将 `>` 和 `>>` 作为箭头来理解。当然,这个箭头的指向也可以反过来。例如,Coen brothers 的一些演员以及他们出演电影的次数保存在 `CBActors` 文件中,就像这样:
|
||||
|
||||
```
|
||||
John Goodman 5
|
||||
John Turturro 3
|
||||
George Clooney 2
|
||||
Frances McDormand 6
|
||||
Steve Buscemi 5
|
||||
Jon Polito 4
|
||||
Tony Shalhoub 3
|
||||
James Gandolfini 1
|
||||
```
|
||||
|
||||
你可以执行这样的命令:
|
||||
|
||||
```
|
||||
sort < CBActors
|
||||
Frances McDormand 6 # 你会得到这样的输出
|
||||
George Clooney 2
|
||||
James Gandolfini 1
|
||||
John Goodman 5
|
||||
John Turturro 3
|
||||
Jon Polito 4
|
||||
Steve Buscemi 5
|
||||
Tony Shalhoub 3
|
||||
```
|
||||
|
||||
就可以使用 [`sort`][4] 命令将这个列表按照字母顺序输出。但是,`sort` 命令本来就可以接受传入一个文件,因此在这里使用 `<` 会略显多余,直接执行 `sort CBActors` 就可以得到期望的结果。
|
||||
|
||||
如果你想知道 Coens 最喜欢的演员是谁,你可以这样操作。首先:
|
||||
|
||||
```
|
||||
while read name surname films; do echo $films $name $surname > filmsfirst.txt; done < CBActors
|
||||
```
|
||||
|
||||
上面这串命令写在多行中可能会比较易读:
|
||||
|
||||
```
|
||||
while read name surname films;\
|
||||
do
|
||||
echo $films $name $surname >> filmsfirst;\
|
||||
done < CBActors
|
||||
```
|
||||
|
||||
下面来分析一下这些命令做了什么:
|
||||
|
||||
* [`while ...; do ... done`][5] 是一个循环结构。当 `while` 后面的条件成立时,`do` 和 `done` 之间的部分会一直重复执行;
|
||||
* [`read`][6] 语句会按行读入内容。`read` 会从标准输入中持续读入,直到没有内容可读入;
|
||||
* `CBActors` 文件的内容会通过 `<` 从标准输入中读入,因此 `while` 循环会将 `CBActors` 文件逐行完整读入;
|
||||
* `read` 命令可以按照空格将每一行内容划分为三个字段,然后分别将这三个字段赋值给 `name`、`surname` 和 `films` 三个变量,这样就可以很方便地通过 `echo $films $name $surname >> filmsfirst;\` 来重新排列几个字段的放置顺序并存放到 `filmfirst` 文件里面了。
|
||||
|
||||
执行完以后,查看 `filmsfirst` 文件,内容会是这样的:
|
||||
|
||||
```
|
||||
5 John Goodman
|
||||
3 John Turturro
|
||||
2 George Clooney
|
||||
6 Frances McDormand
|
||||
5 Steve Buscemi
|
||||
4 Jon Polito
|
||||
3 Tony Shalhoub
|
||||
1 James Gandolfini
|
||||
```
|
||||
|
||||
这时候再使用 `sort` 命令:
|
||||
|
||||
```
|
||||
sort -r filmsfirst
|
||||
```
|
||||
|
||||
就可以看到 Coens 最喜欢的演员是 Frances McDormand 了。(`-r` 参数表示降序排列,因此 McDormand 会排在最前面)
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
|
||||
via: https://www.linux.com/blog/learn/2019/1/understanding-angle-brackets-bash
|
||||
|
||||
作者:[Paul Brown][a]
|
||||
选题:[lujun9972][b]
|
||||
译者:[HankChow](https://github.com/HankChow)
|
||||
校对:[校对者ID](https://github.com/校对者ID)
|
||||
|
||||
本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出
|
||||
|
||||
[a]: https://www.linux.com/users/bro66
|
||||
[b]: https://github.com/lujun9972
|
||||
[1]: https://www.linux.com/blog/2019/1/bash-shell-utility-reaches-50-milestone
|
||||
[2]: https://www.linux.com/blog/learn/2019/1/linux-tools-meaning-dot
|
||||
[3]: https://linux.die.net/man/1/wc
|
||||
[4]: https://linux.die.net/man/1/sort
|
||||
[5]: http://tldp.org/HOWTO/Bash-Prog-Intro-HOWTO-7.html
|
||||
[6]: https://linux.die.net/man/2/read
|
||||
|
Loading…
Reference in New Issue
Block a user