【问题标题】:How to split a line into words separated by one or more spaces in bash? [duplicate]如何在bash中将一行拆分为由一个或多个空格分隔的单词? [复制]
【发布时间】:2010-12-30 20:33:58
【问题描述】:

我意识到如何在 python 中做到这一点,只需使用

line = db_file.readline()
ll=string.split(line)

但是我怎样才能在 bash 中做同样的事情呢?真的可以这么简单吗?

【问题讨论】:

  • 我认为你的意思是 Python 中的 ll=str.split(line)

标签: bash


【解决方案1】:

read-a 选项将允许您拆分由$IFS 中包含的字符读取的行。

【讨论】:

  • #!/bin/bash filename=$1 while read LINE do echo $LINE | read -a done
  • 不,-a 将是第一次读取的参数。 bash 命令行中的“帮助阅读”会,嗯...帮助。
  • @asdf:看起来像这样:filename=$1; while read -a LINE; do echo "$LINE"; done < "$filename"
【解决方案2】:
$ line="these are words"
$ ll=($line)
$ declare -p ll  # dump the array
declare -a ll='([0]="these" [1]="are" [2]="words")'
$ for w in ${ll[@]}; do echo $w; done
these
are
words

【讨论】:

  • +1 教我 -p 选项
【解决方案3】:
s='foo bar baz'
a=( $s )
echo ${a[0]}
echo ${a[1]}
...

【讨论】:

  • 内联变量:BAR="$(a=($value);echo ${a[1]})"
  • 这给出了一个错误 ./deploy.sh: 7: ./deploy.sh: Syntax error: "(" 意外第 7 行是 a=( $s ) 所在的位置。
  • @isuru-buddhika 这个语法是 Bash 特有的;如果你的脚本不是由 Bash 执行的(例如,在 Debian 或 Ubuntu 系统上以 #!/bin/sh 开头),你会得到那个语法错误。如果脚本像bash deploy.sh 那样执行或者第一行更改为#!/usr/bin/env bash,它应该可以工作。
  • (我无法添加问题的答案,因此添加为评论)如果您只想从(例如)命令输出中提取第一个或最后一个单词,您可以简单地使用 shell可变字符串替换运算符,用于删除字符串的第一个或最后一个部分。 desktop:~$ var="first last" desktop:~$ first_word=${var%% *} # space star ! desktop:~$ echo $first_word first desktop:~$ last_word=${var##* } # star space ! desktop:~$ echo $last_word last
【解决方案4】:

这取决于您所说的拆分是什么意思。如果你想迭代一行中的单词,它在一个变量中,你可以迭代。例如,假设变量linethis is a line。然后你可以这样做:

for word in $line; do echo $word; done

这将打印:

this
is
a
line

for .. in $var 使用$IFS 中的值拆分$var,其默认值表示“拆分空格和换行符”。

如果你想从用户或文件中读取行,你可以这样做:

cat $filename | while read line
do
    echo "Processing new line" >/dev/tty
    for word in $line
    do
        echo $word
    done
done

对于其他任何事情,您都需要更加明确并更详细地定义您的问题。

注意:已编辑以删除 bashism,但我仍然保留 cat $filename | ...,因为我更喜欢它而不是重定向。

【讨论】:

  • 无用使用cat - 像这样重定向文件:done < "$filename"。此外,在此上下文中使用 for value in "${var[@]}" 而不是索引变量。虽然在这种情况下数组可能是连续的,但 Bash 支持稀疏数组,${#var[@]} 可能不是最后一个条目(尽管${var[@]: -1} 将是,indices=(${!a[@]}); count=${#indices[@]} 将给出索引列表和正确的计数)
  • @Dennis:所有优点。由于某种原因,我习惯了cat a | blah 而不是`blah
  • 如果您在 $line 中有一个好的星号 (*),此方法将失败。 Bash 会用当前目录中的文件列表替换 if。
【解决方案5】:

如果你已经在变量 $LINE 中有你的文本行,那么你应该可以说

for L in $LINE; do
   echo $L;
done

【讨论】:

    【解决方案6】:

    这样做

    while read -r line
    do
      set -- $line
      echo "$1 $2"
    done <"file"
    

    $1、$2 等将是您的第一个和第二个拆分“字段”。使用 $@ 获取所有值。使用 $# 获取“字段”的长度。

    【讨论】:

    • 请注意,如果您的 $line 包含例如*,这将在执行set -- $line 时被 bash 扩展,这会产生惊人的效果。
    • 1) “--”有什么作用? 2) 扩展 * 有什么惊人的效果?
    【解决方案7】:

    如果您想从该行中获取特定单词,awk 可能会很有用,例如

    $ 回声 $LINE | awk '{打印 $2}'

    打印 $LINE 中的第二个空格分隔的单词。您还可以拆分其他字符,例如

    $ echo "5:6:7" | awk -F: '{打印 $2}' 6

    【讨论】:

    • 这就是我刚刚开始使用awk的原因。与数组创建和额外行不同。 -F: 确实从 : 在一行中爆炸。喜欢它,谢谢。
    • 进一步:echo "5::6:7" | awk -F:: '{print $2}' 6:7 (与剪切不同,它只需要一个字符作为分隔符)
    【解决方案8】:

    更简单,

    echo $line | sed 's/\s/\n/g'
    

    \s --> 空白字符(空格、制表符、NL、FF、VT、CR)。在许多 系统也有效 [:space:]

    \n --> 换行

    【讨论】:

      【解决方案9】:
      echo $line | tr " " "\n"
      

      给出的输出类似于上面大多数答案的输出;不使用循环。


      在您的情况下,您还提到了ll=&lt;...output...&gt;
      所以,(鉴于我不太了解 python 并假设您需要将输出分配给变量),

      ll=`echo $line | tr " " "\n"`
      

      应该足够了(记住echo "$ll"而不是echo $ll

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2018-06-09
        • 2011-12-30
        • 2019-11-24
        • 2021-01-22
        • 1970-01-01
        • 2010-11-30
        • 1970-01-01
        相关资源
        最近更新 更多