【问题标题】:simple 6-line bash script while loop... WHAT is wrong?简单的 6 行 bash 脚本 while 循环......出了什么问题?
【发布时间】:2012-11-30 19:22:15
【问题描述】:

我有一个 TSV 文件,如下所示:

input.tsv
Apple       Give me an iPad. 
Apple       I love MacBookPro!
Google      Buy the Nexus.
Google      Chromebooks are easy to use.
Microsoft   Surface is awesome.

第一列是一个单词,第二列是一个句子。我只是希望我的输出看起来像

apple.txt
Give me an iPad.
I love the MacBook Pro!

google.txt
Buy the Nexus.
Chromebooks are easy to use.

这是我的脚本:

while read -r company sentence
do
    for line in $sentence
    do
        printf "$line\n" >> $company.txt
    done
done < input.tsv

但输出是每行标记一个单词,例如:

apple.txt
Give
me
an
iPad

我不知道出了什么问题!!!任何人都可以帮忙吗?

【问题讨论】:

    标签: bash unix loops while-loop


    【解决方案1】:

    while read 循环已经完成了整行,所以我不确定for 循环的意图是什么。您正在遍历单词并每行输出一个。

    此外,如果行中有百分号或反斜杠,您的 printf 也不安全。

    while read -r company sentence; do
      printf '%s\n' "$sentence" >>"$company.txt"
    done < input.tsv
    

    此外,大多数 Unixy 文件系统都区分大小写(OS X 上的默认设置是一个明显的例外);如所写,这将创建文件Apple.txtGoogle.txt 而不是apple.txtgoogle.txt。如果您想要小写文件名,那么您需要稍微更改该附加重定向的目标。

    如果您使用的是 bash 4,则只需将 "$company.txt" 替换为 "${company,,}.txt"。在较旧的 bash 版本中,您可以执行 &gt;&gt;"$(tr A-Z a-z &lt;&lt;&lt;"$company").txt" 或类似操作。

    【讨论】:

    • 更容易小写:declare -l company 并让 bash 为您进行大小写转换。
    • @glennjackman true,但 bash 也在 ${company,,} 表达式中进行大小写转换,只是在扩展时而不是读取时。 :) 如果您使用的是 bash 4,您当然可以使用 declare。使用 bash 3(嘿,Apple!已经升级了!),您仍然会遇到类似 tr 调用的问题。
    【解决方案2】:

    放弃for line in $sentence? (让它更小!)

    while read -r company sentence
    do
        printf '%s\n' "$sentence" >> $company.txt
    done < input.tsv
    

    【讨论】:

    • 哇,你比我快。但是你应该使用printf '%s\n' "$sentence" 而不是printf "$sentence\n"
    • 呵呵,我就这样吧,很少使用printf。如果由我决定,我会让它变得更简单echo "$sentence" &gt;&gt; $company.txt
    • 这行得通!马克, printf '%s\n' "$sentence" 和简单的 printf "$sentence" 有什么区别?
    • 第一个参数是格式(可以包含普通文本),其余的都是参数。如果您的$sentence 中存在格式字符串中的“特殊”数据(%s、文字\n 等),它们将被解释而不是按原样存储。
    • 使用裸echo 几乎适用于所有情况,但仍有一些病态情况(例如$sentence 等于-n。:)) 使用具有显式格式的printf字符串是最安全的通用解决方案。
    猜你喜欢
    • 2020-02-17
    • 2012-07-06
    • 2013-09-02
    • 1970-01-01
    • 2014-03-09
    • 1970-01-01
    • 2011-06-17
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多