我使用以下格式#{string:start:length}
逐行从wget的.listing
文件中提取文件名。
该文件的格式是我认为我们都熟悉的:
04-30-13 01:41AM 7033614 some_archive.zip
04-29-13 08:13PM <DIR> DIRECTORY NAME 1
04-29-13 05:41PM <DIR> DIRECTORY NAME 2
所有文件名都以pos:40开头,因此将:start
设置为39,没有:length
应该(并且确实)返回每行的文件名:
#!/bin/bash
cat .listing | while read line; do
file="${line:40}"
echo $file
done
正确回归:
some_archive.zip
DIRECTORY NAME 1
DIRECTORY NAME 2
但是,如果我再获得更多创意,那就会破坏:
#!/bin/bash
cat .listing | while read line; do
file="${line:40}"
dir=$(echo $line | egrep -o '<DIR>' | head -n1)
if [ $dir ]; then
echo "the file $file is a $dir"
fi
done
返回:
$ ./test.sh
is a <DIR>ECTORY NAME 1
is a <DIR>ECTORY NAME 2
是什么给出的?我丢失了“文件”,其余的测试看起来像是从pos:0打印在“文件DIRECTORY NAME 1”之上。
这很奇怪,它的含义是什么?
答案 0 :(得分:1)
答案是,随着我的进步,我越来越多地学习linux,它是非打印控制字符。
仅为打印字符添加管道egrep
解决了问题:
#!/bin/bash
cat .listing | while read line; do
file=$(echo ${line:39} | egrep -o '[[:print:]]+' | head -n1)
dir=$(echo $line | egrep -o '<DIR>' | head -n1)
if [ $dir ]; then
echo "the file $file is a $dir"
fi
done
正确回归:
$ ./test.sh
the file DIRECTORY NAME 1 is a <DIR>
the file DIRECTORY NAME 2 is a <DIR>
希望有一种更好的方法可视化这些控制字符,但上面所做的基本上是取字符串段,拉出第一个可打印字符串,并将其分配给变量。
我假设在行的末尾有一个控制字符,它将光标返回到行的开头。导致其余的echo
被打印出来,覆盖以前的字符。'
奇
答案 1 :(得分:1)
您可以使用脚本第一行的\r
命令从整个文件中删除tr
个控制字符:
#!/bin/bash
cat .listing | tr -d '\015' | while read line; do
file="${line:39}"
dir=$(echo $line | egrep -o '<DIR>' | head -n1)
if [ $dir ]; then
echo "the file $file is a $dir"
fi
done