【问题标题】:Parsing text in bash script在 bash 脚本中解析文本
【发布时间】:2014-11-02 19:00:41
【问题描述】:

我有这段文字

hello world@helloworld@/dev/zero@inout/helloworld.out
hello world with warnings@warnings@/dev/zero@inout/helloworld.out
echo test@myecho@inout/echo.in@inout/echo.out
echo failtest@myecho@inout/echo.in@inout/helloworld.out
memleaks pass@memleaks@inout/memleaks.6.in@inout/memleaks.6.out
memleaks fail@memleaks@inout/memleaks.11.in@inout/memleaks.11.out

我想运行一个 bash 循环,在每次运行中我将读取一行并获得 4 个变量 每个直到@(没有@) 并知道我是什么行号 我到此为止

(( index=0 ))
for read line
do
    (( index+=1 ))
    var1=
    var2=
    var3=
    var4=
done

我想得到的是

var1=hello world
var2=helloworld
var3=/dev/zero
var4=inout/helloworld.out

有没有办法在 1 行中做到这一点?

【问题讨论】:

标签: linux bash shell unix ubuntu


【解决方案1】:

Bash(显然)内置了文件读取和令牌拆分。要在自定义分隔符上拆分,请将 IFS 设置为合适的值。

oldIFS=$IFS
IFS=@
while read -r var1 var2 var3 var4; do
    : stuff
done <file

如果您的脚本中的任何其他内容依赖于常规的空格分隔行为,您需要 oldIFS。一种常见的安排是将拆分放在具有local 值为IFS 的函数中。

read-r 选项指定了正常的行为,应该是默认的,但不能因为遗留原因。如果您正在解析实际的 shell 代码,则没有此选项的行为是有意义的,但通常不是。

【讨论】:

  • 为什么需要oldIFSwhile IFS=@ read -r ... 怎么了?
【解决方案2】:

您也可以在awk 中使用-F 标志执行此操作,该标志指定字段分隔符(相当于$IFS)。

例如,转储每一行中的字段:

while read line ; do
  echo $line | awk -F '@' '{ print $1,$2,$3,$4 }'
done

【讨论】:

    猜你喜欢
    • 2013-08-30
    • 2020-02-09
    • 2013-07-24
    • 2016-02-08
    • 2010-12-06
    • 1970-01-01
    • 1970-01-01
    • 2012-05-20
    • 2021-12-03
    相关资源
    最近更新 更多