【问题标题】:"Read" skipping last word on each line“阅读”跳过每行的最后一个单词
【发布时间】:2012-03-15 20:18:05
【问题描述】:

我从一个 for 循环中得到一些奇怪的行为,该循环读取文件中的每一行并在每一行之后读取每个单词。 Read 会跳过每行的最后一个单词。我想我可能必须指定空格和换行符都是分隔符,但我还没有找到如何做到这一点。以下是脚本中重要的部分:

  cat $i | while read line    
    do
        echo $line
        sleep 1
        #Process each word
        echo $line | while read -d ' '  word
        do
            echo $word
            sleep 1
        done
    done

【问题讨论】:

  • 避免不必要的cats:while read line; do …; done < $i

标签: linux bash scripting


【解决方案1】:

你看到How to split one string into multiple strings separated by at least one space in bash shell?了吗?也许你可以这样做:

for word in $line
do
    echo $word
    sleep 1
done

【讨论】:

  • 这似乎很有魅力,我想我是太沉迷于使用 read 了,因为我用它来读取文件。
  • 不确定,但我认为这会使 $line 受到通常的 shell 扩展的影响,结果可能比你想要的要多。您需要试验一下包含双引号和单引号以及反引号(平衡和不平衡)以及美元符号 ($) 的输入行会发生什么。如果这对您来说是个问题,您可以考虑基于我在下面建议的fmt 的解决方案。
【解决方案2】:

for 命令的语法是:

      for name [ [in [words ...] ] ; ] do commands; done

扩展单词,并为结果列表中的每个成员执行一次命令,名称绑定到当前成员。

cat $i | while read line    
do
    echo $line
    sleep 1
    #Process each word
    for word in $line
    do
        echo $word
        sleep 1
    done
done

【讨论】:

  • 这似乎是一种魅力,我想我是因为使用它来读取文件而对使用 read 太着迷了
【解决方案3】:

尝试使用 cut 命令而不是 read -d

【讨论】:

    【解决方案4】:

    如果您不需要记住行边界,fmt 命令会很有用。 fmt 将 stdin 上的纯文本重排为给定的最大行长,因此如果您给它一个最大行长,它最终会将输入的每个单词拆分到自己的行中。对于你的问题,也许

    cat $1 |
    fmt -1 |
    while read word
    do
        # do something with $word
    end
    

    请注意,您在这里丢失了所有原始行边界,并且您依赖于fmt 对单词的定义。如果您出于某种原因确实需要线边界,您可以考虑类似

    cat $1 |
    while read line
    do
        # do something with $line
        echo "$line" | 
        fmt -1 |
        while read word
        do
            # do something with $word
        done
    done
    

    【讨论】:

      猜你喜欢
      • 2013-06-15
      • 1970-01-01
      • 1970-01-01
      • 2015-08-27
      • 1970-01-01
      • 2023-03-31
      • 2019-01-28
      • 2022-01-05
      • 1970-01-01
      相关资源
      最近更新 更多