我的 Bash 作业的一部分包括读取文本文件,然后将每一行分成单词并使用它们。
单词由 分隔|
,行由 分隔\n
。我们被告知使用该tr
命令,但我找不到优雅的解决方案。
一个例子:
Hello | My | Name | Is | Bill
应该给:
Hello
My
Name
Is
Bill
每次迭代一个词。
您只需要一次调用tr
来完成这项工作:
$ echo "Hello | My | Name | Is | Bill" | tr -cs '[:alpha:]' '\n'
Hello
My
Name
Is
Bill
$
该-c
选项用于第一个模式中字符的“补码”;该-s
选项“挤压”出重复的替换字符。因此,任何不是字母的内容都会转换为换行符,但连续的换行符会被压缩为单个换行符。
显然,如果您需要保留“其他人 | 可以| 来电 | 我 | Fred' 与输出的第一行中的两个词,那么您必须更加努力地工作:
$ echo "Everyone else | can | call | me | Fred" |
> tr '|' '\n' |
> sed 's/ *$//;s/^ *//'
Everyone else
can
call
me
Fred
$
此处的sed
脚本删除了前导和尾随空格,使中间空格保持不变。如果需要,您可以用一个空白替换多个空白,依此类推。您不能用于tr
有条件地替换给定字符(例如,更改一些空白并保留其他字符)。
使用 tr:
echo "Hello | My | Name | Is | Bill" | tr -s '\| ' '\n'
或者,如果您决定给 awk 一个机会:
echo "Hello | My | Name | Is | Bill" | awk -F '\|' '{for (i=1; i<=NF; i++) {
sub(/ /, "", $i); print $i}}'
其他一些选项:
awk:
awk -F'\\| ' -v OFS="\n" '$1=$1'
例子:
kent$ echo "Hello | My | Name | Is | Bill" |awk -F'\\| ' -v OFS="\n" '$1=$1'
Hello
My
Name
Is
Bill
grep
grep -o '[^ |]*'
例子:
kent$ echo "Hello | My | Name | Is | Bill"|grep -o '[^ |]*'
Hello
My
Name
Is
Bill
sed
sed 's/ | /\n/g'
例子:
kent$ echo "Hello | My | Name | Is | Bill" |sed 's/ | /\n/g'
Hello
My
Name
Is
Bil
我最喜欢的 perl :)
echo "Hello | My | Name | Is | Bill" | perl -pe 's/\s*\|\s*/\n/g'
也会删除多余的空格,所以
echo "Hello | My | Name | Is | Bill" | perl -pe 's/\s*\|\s*/\n/g' | cat -vet
将打印
Hello$
My$
Name$
Is$
Bill$
文件温度:你好| 我的 | 姓名 | 是 | 账单
$ cat temp | tr '|' '\n' | sed 's/^ *//g'
Hello
My
Name
Is
Bill
$
sed 部分去掉了前导空格(因为在 '|' 和单词之间有一个空格。这也适用于“大家好 | 我的 | 姓名 | 是 | 比尔”:
$ cat temp | tr '|' '\n' | sed 's/^ *//g'
Hello everyone
My
Name
Is
Bill
$
这段代码应该这样做,转换 '|' 换行,删除前导/尾随空格:
echo "Hello | My | Name | Is | Bill" | tr '|' '\n' | tr -d [:blank:]