Bash 如果用制表符隔开,则无法识别单词
我有一个问题,就是如果文本文件中的单词是用制表符而不是空格隔开的,程序就无法读取每个单词 例如,下面是一个文件 part_Q.txt:Bash 如果用制表符隔开,则无法识别单词,bash,shell,sh,Bash,Shell,Sh,我有一个问题,就是如果文本文件中的单词是用制表符而不是空格隔开的,程序就无法读取每个单词 例如,下面是一个文件 part_Q.txt: NWLR35MQ 649 HCDA93OW 526 abc 1 def 2 ghi 3 NWLR35MQ 649 HCDA93OW 526 def 2 ghi 3 NWLR35MQ 649 HCDA93OW 526 abc 1 def 2 ghi 3 #!/bin/sh tempCtr=0 realCtr=0 copyCtr=
NWLR35MQ 649
HCDA93OW 526
abc 1
def 2
ghi 3
NWLR35MQ
649
HCDA93OW
526
def
2
ghi
3
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
- 请注意,在“abc”和“1”之间有一个选项卡,而不是空格
- 还要注意,“NWLR35MQ”和“649”之间没有制表符,但都是空格。第二行也一样
NWLR35MQ 649
HCDA93OW 526
abc 1
def 2
ghi 3
NWLR35MQ
649
HCDA93OW
526
def
2
ghi
3
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
但是,如果我在文件中用空格替换“abc”和“1”之间的制表符,那么它将正确输出,如下所示
预期输出:
NWLR35MQ 649
HCDA93OW 526
abc 1
def 2
ghi 3
NWLR35MQ
649
HCDA93OW
526
def
2
ghi
3
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
它正确显示文件中的所有单词。如何显示所有单词,而不考虑制表符或空格?它应该显示两种情况下的所有单词。似乎该程序将tab视为一个字符
下面是源代码:
NWLR35MQ 649
HCDA93OW 526
abc 1
def 2
ghi 3
NWLR35MQ
649
HCDA93OW
526
def
2
ghi
3
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
#/垃圾箱/垃圾箱
tempCtr=0
realCtr=0
copyCtr=0
而IFS=read-r行| |[[-n$line]];做
如果=“”
tempCtr=0
对于$line中的单词;做
临时[$tempCtr]=“$word”
让“tempCtr++”
完成
#如果每行正好有2个字段,则存储ID和数量
如果[$tempCtr-等式2]
然后
部分Q[$realCtr]=${temp[$copyCtr]}
让“realCtr++”
让“copyCtr++”
部分Q[$realCtr]=${temp[$copyCtr]}
让“realCtr++”
copyCtr=0
fi
完成
您可以通过一行代码来解决这个问题(如示例中所示)
cat part_Q.txt | tr $'\t' $'\n' | tr -s ' ' $'\n'
哪个
- 首先
将选项卡转换为新行,然后tr
也解析空间(tr
)-s
tr
,在bash中的\t
ab和\n
ewline字符之前需要$
既然已经提到了这一点,
awk
也有帮助:
awk 'NF==2{print $1"\n"$2}' part_Q.txt
其中,
NF==2
甚至只考虑使用带有2个“单词”的行。您想做什么?如果输出是您唯一的目标,那么这可以很容易地实现:
$ 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
$catAwk比循环快,但以下是如何通过循环实现这一点:
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'
realCtr=0
读取时-rx1x2x3;做
如果[-n“${x2}”]&&[-z“${x3}”];然后
回声2=$x2
第Q部分[realCtr]=“${x1}”
((realCtr++)
part_Q[realCtr]=“${x2}”
((realCtr++)
fi
完成
将IFS='
更改为IFS=$'\t'
解决了这个问题。只是一个想法:您可以尝试预处理文件(或行)并用空格替换制表符。BTW <代码> AWK < /代码>绝对不会有这样的问题。请更改<代码> IFS= ''/c> > <代码> IFS= $'\/'代码>,但请考虑<代码> AWK < /代码>只删除<代码> IFS= 和<代码> IFS= ''/COD>代码>读取行
line将读取一行,无论是否存在空格<当您可以awk'NF==2{print$1”\n“$2}”part_Q.txt
时,$line中的单词的code>默认情况下将拆分word.uooc。已调整,谢谢。通过从tr示例复制/粘贴使用管道您也不需要cat
tr$'\t'$'\n“不必要地使用IFS
。即使不设置它,它也可以工作。IFS的默认值足够了。