0

次の形式#{string:start:length}を使用して、wget の.listingファイルからファイル名を 1 行ずつ抽出しています。

ファイルのフォーマットは、私たちがよく知っているものだと思います:

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 に設定すると、no :lengthshould (および do) で各行のファイル名が返されます。

#!/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

答えは、進行するにつれて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 に答える
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 に答える