0

我使用以下格式逐行#{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 的“文件目录名称 1”之上。

很奇怪,这是怎么回事?

4

2 回答 2

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
于 2013-05-07T15:47:44.697 回答
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被打印在那里,覆盖以前的字符。

奇怪的。

于 2013-05-07T14:32:21.227 回答