我现在有以下内容:
for file in *
do
list="$list""$file "`cat $file | wc -l | sort -k1`$'\n'
done
echo "$list"
这是打印:
fileA 10
fileB 20
fileC 30
然后我想循环浏览$list
和cut
第2列并执行计算。
当我这样做时:
for line in "$list"
do
noOfLinesInFile=`echo "$line" | cut -d\ -f2`
echo "$noOfLinesInFile"
done
打印:
10
20
30
但是for loop
只输入一次。在此示例中,它应该输入loop
3次。
有人可以告诉我在这里应该做些什么来实现这个目标吗?
答案 0 :(得分:1)
如果引用变量
for line in "$list"
只有一个单词,所以循环只执行一次。
如果没有引号,$line
将会填充$list
中找到的任何单词,这也不是您想要的单词,因为它会逐个处理值,而不是行。
您可以将$IFS
变量设置为换行符,以便在换行符上拆分$list
:
IFS=$'\n'
for line in $list ; do
...
done
不要忘记将IFS重置为原始值 - 要么将整个部分放入子shell中(如果没有变量应该在循环中存活)
(
IFS=$'\n'
for ...
)
或备份值:
IFS_=$IFS
IFS=$'\n'
for ...
IFS=$IFS_
...
done
答案 1 :(得分:0)
这是因为shell中的列表只是使用空格作为分隔符来定义。
# list="a b c"
# for i in $list; do echo $i; done
a
b
c
# for i in "$list"; do echo $i; done
a b c
在你的第一个循环中,你实际上并没有在shell sens中建立一个列表。 您应该为循环,附加或剪切设置默认分隔符以外的其他分隔符。
答案 2 :(得分:0)
改为使用数组:
#!/bin/bash
files=()
linecounts=()
for file in *; do
files+=("$file")
linecounts+=("$(wc -l < "$file")")
done
for i in "${!files[@]}" ;do
echo "${linecounts[i]}"
printf '%s %s\n' "${files[i]}" "${linecounts[i]}" ## Another form.
done
虽然可以更简单地完成printf '%s\n' "${linecounts[@]}"
。
答案 3 :(得分:0)
wc -l
只输出一个值,因此您无需对其进行排序:
for file in *; do
list+="$file "$( wc -l < "$file" )$'\n'
done
echo "$list"
然后,您可以使用while循环逐行读取列表:
while read file nlines; do
echo $nlines
done <<< "$list"
如果任何文件名都有空格,那么while循环是脆弱的。这有点强大:
while read -a words; do
echo ${words[-1]}
done <<< "$list"