1

その一部が「sed」を利用してファイル名をそのファイルの各行の終わりにタグ付けし、出力をマスターリストにダンプするスクリプトを作成しようとしています。私に問題を与えるスクリプトの部分はここにあります:

DIR=/var/www/flatuser
FILES=$DIR/*
for f in $FILES
do
    echo "processing $f file...."
    sed -i "s/$/:$f/" $f
    cat $f >> $DIR/master.txt
done

問題は、「sed」ステートメントがforループの外では正常に機能することですが、スクリプトに配置すると、ドル記号の解釈に問題があると思います。変数を解釈するために考えられる「と」のほぼすべての組み合わせを試しましたが、各行の最後に「$ f」が連続して配置されるか、完全に失敗します。

ご入力いただきありがとうございます。

4

4 に答える 4

5

ドル記号をエスケープする必要があります。

sed -i "s/\$/:$f/" "$f"

シェルがそれを文字通りに渡すようにしsedます。

変数の引用に関するCharlesDuffyのポイントを拡張するには、次のようにします。

DIR=/var/www/flatuser
for f in "$DIR"/*
do
    echo "processing $f file...."
    sed -i "s/\$/:${f##*/}/" "$f"
    cat "$f" >> "$DIR/master.txt"
done

$FILESファイル名にスペースが含まれている場合、ファイル名のリストを;に割り当てると、それについて何もするのに遅すぎます。ファイル名に属するスペースとファイル名を区切るスペースを区別できなくなりました。代わりに配列を使用することもできますが、グロブを直接forループに配置する方が簡単です。配列の使用方法は次のとおりです。

DIR=/var/www/flatuser
FILES=( "$DIR"/* )
for f in "${FILES[@]}"
do
    echo "processing $f file...."
    sed -i "s/\$/:${f##*/}/" "$f"
    cat "$f" >> "$DIR/master.txt"
done

sedを使用しないバージョンの場合-i、インプレース編集をシミュレートするために必要な一時ファイルを明示的に処理する方法は次のとおりです。

t=$(mktmp sXXXX); sed "s/\$/:$f/" "$f" > "$t"; mv "$t" "$f" && rm "$t"
于 2013-03-22T16:00:11.323 に答える
3

個人的に、私はこのようにします:

dir=/var/www/flatuser
for f in "$dir"/*; do
  [[ $f = */master.txt ]] && continue
  while read -r; do printf '%s:%s\n' "$REPLY" "${f##*/}"; done <"$f"
done >/var/www/flatuser/master.txt

ファイルをインプレースで変更することはないため、sed -i複数回実行しても安全です(sed -iバージョンでは、実行するたびにファイルに名前がインプレースで追加されるため、各行で終了します。ファイル名のコピーが複数ある)。

また、sed -iPOSIXで指定されていないため、すべてのオペレーティングシステムで指定されているわけではありません。

于 2013-03-22T16:11:54.023 に答える
0

問題はドル記号ではありません。変数$fには「/」文字が含まれており、sedはそれを使用して式を区切ります。区切り文字として「@」を使用してみてください。

DIR=/var/www/flatuser
FILES=$DIR/*
for f in $FILES
do
    echo "processing $f file...."
    sed -i s@"$"@:"$f"@ $f
    cat $f >> $DIR/master.txt
done
于 2013-03-22T16:24:08.040 に答える
0

それは古いですが、多分それは誰かを助けます。先頭のディレクトリを削除するためにファイルにベースネームを付けてみませんか

DIR=/var/www/flatuser
FILES=( "$DIR"/* )
for f in "${FILES[@]}"
do
    echo "processing $f file...."
    b=`basename $f`
    sed -i "s/\$/:${b##*/}/" "$b"
    cat "$f" >> "$DIR/master.txt"
done

未検証 ...

于 2014-07-16T08:09:39.713 に答える