如果用制表符间隔,则无法识别单词

时间:2017-03-22 18:57:53

标签: bash shell sh

我有一个问题,即如果文本文件中的单词是用制表符而不是空格分隔,程序就无法读取每个单词。

例如,这是文件。

part_Q.txt:

NWLR35MQ        649
HCDA93OW        526
abc 1
def 2
ghi 3
  • 请注意" abc"和" 1",有一个标签,而不是空格。
  • 还要注意" NWLR35MQ"和" 649",没有标签,但都是空格。第二行也一样。

输出:

NWLR35MQ
649
HCDA93OW
526
def
2
ghi
3

但是,如果我在" abc"之间更换标签。和" 1"通过文件中的空格,然后输出正确如下,

预期输出:

NWLR35MQ
649
HCDA93OW
526
abc
1
def
2
ghi
3

它正确显示文件中的所有单词。如何显示所有单词而不管制表符或空格?它应该显示两种情况下的所有单词。似乎该程序将制表符视为一个字符。

以下是源代码:

#!/bin/sh

tempCtr=0
realCtr=0
copyCtr=0
while IFS= read -r line || [[ -n $line ]]; do
   IFS=' '
   tempCtr=0
   for word in $line; do
    temp[$tempCtr]="$word"
    let "tempCtr++"
   done 
   # if there are exactly 2 fields in each line, store ID and quantity
   if [ $tempCtr -eq 2 ]
   then
    part_Q[$realCtr]=${temp[$copyCtr]}
    let "realCtr++"
    let "copyCtr++"
    part_Q[$realCtr]=${temp[$copyCtr]}
    let "realCtr++"
    copyCtr=0
   fi
done < part_Q.txt

for value in "${part_Q[@]}"; do
    echo $value
done

4 个答案:

答案 0 :(得分:0)

您可以通过一行代码解决此问题(如您的示例所示)

cat part_Q.txt | tr $'\t' $'\n' | tr -s ' ' $'\n'

其中

  • 首先tr将标签转换为换行符,然后
  • tr同时提供空间(-s

注意:对于tr,您需要在bash中的$ ab和\t ewline字符之前使用\n

既然已经提到过,awk也可以提供帮助:

awk 'NF==2{print $1"\n"$2}' part_Q.txt

NF==2甚至只关注使用2个单词的行。

答案 1 :(得分:0)

你想做什么?如果输出是您唯一的目标,那么这很容易实现:

$ cat <<EOF | sed -E 's/[[:blank:]]+/\n/'
NWLR35MQ        649
HCDA93OW        526
abc 1
def 2
ghi 3
EOF

NWLR35MQ
649
HCDA93OW
526
abc
1
def
2
ghi
3

答案 2 :(得分:0)

Awk比循环更快,但是你可以通过循环实现这个:

realCtr=0
while read -r x1 x2 x3; do
   if [ -n "${x2}" ] && [ -z "${x3}" ]; then
      echo 2=$x2
    part_Q[realCtr]="${x1}"
   (( realCtr++ ))
    part_Q[realCtr]="${x2}"
   (( realCtr++ ))
   fi
done  < part_Q.txt

echo "Array (2 items each line):"
echo "${part_Q[@]}" | sed 's/[^ ]* [^ ]* /&\n/g'

答案 3 :(得分:0)

改变IFS =&#39; &#39;到IFS = $&#39; \ t&#39;解决了! 谢谢你@anubhava