forループ内で実行中にwcにパイプされたlsの結果をどのように取得しますか?

forループ内で実行中にwcにパイプされたlsの結果をどのように取得しますか?

したがって、データをファイルにダンプするのではなく、単一のコマンドで作成し、ファイルをcatし、出力をwc -lにパイプしました。完全なコード行は次のとおりです。

for file in `grep Rawdata freeze2-1.out | awk '{print $6}'`
 do
  ls -1 /appdata/frozen_files/$file | wc -l
 done

ただし、出力は、出力全体の合計ではなく、1行あたりの数を提供します。とにかく、すべてのファイルに対して単一の数字の出力を取得しながらこの操作を実行できますか?または、ファイルにリダイレクトして別の手順を実行する必要がありますか?

ベストアンサー1

Freeze2-1.outファイルでは、フィールド6という名前のディレクトリ内のファイルの総数を計算しようとしますが、ファイルの対応する行のどこかに「Rawdata」が表示された場合にのみ適用されます。

wc -l元の投稿の主なエラーは、単に個々の行の計算を要求したロジックまたはバッチの間違いです。~へループ全体で提供される行の総数を要求するループ。これは、ほとんどの既存の回答が修正されることです。

「自宅で遊べるように」サンプルFreeze2-1.outファイルを作成しました。ここに入れた内容は次のとおりです。

Rawdata 2 3 4 5 file1
Rawdata 2 3 4 5 file2
Rawdata 2 3 4 5 file3

私も一つ満たした比較的「appdata/frozen_files」というディレクトリは、上記のフィールド6に基づいています。実際のパスは次のとおりです。純粋な/appdata/frozen_files で始まるパス。 file1に1個、file2に2個、file3に3個、合計6個のファイルを入れました。

私が提案したい最初の改善点は、awkがパターンマッチングを実行できるようにすることで、grepとを組み合わせることですawkローマ・ペレクレストこれは彼らが答えた内容でもあります:

awk '/Rawdata/ { print $6 }' freeze2-1.out

出力例は次のとおりです。

file1
file2
file3

ここでは、awkがスペース、タブ、および改行に基づいてフィールドを分割するため、特にフィールド6を印刷することは、出力の各行にスペースなしで1つの単語があることを意味します。

ディレクトリ内のファイル数を数える方法はいくつかあります。使用されたls -1 | wc -lものただし、改行を含むファイル名の特殊な場合は失敗します。これらのファイルを手動で作成できますtouch $'file\nname'。 awkは改行で区切られた入力行を読むので、ここでは特別なケースには会いませんが、言及したかったのです。たとえば、

# create the file
$ touch $'file\nname'

# check the listing; looks okay so far
$ ls -1
appdata
file?name
freeze2-1.out

# count them up
$ ls -1 | wc -l
4 

# woops! should be 3!

したがって、ディレクトリ内のファイル数を数える2つの異なる方法を紹介します。

最初の方法はset組み込み関数を使用して引数を取得し、$1、$2、$3などの位置引数に変換します。

$ sum=0
$ for file in $(awk '/Rawdata/ { print $6 }' freeze2-1.out)
  do
    set -- "appdata/frozen_files/${file}/"*
    sum=$((sum + $#))
  done
$ echo "$sum"
6

これはカウンタをsum0に初期化し、awk出力のファイル名を繰り返します。これはset、引用されたディレクトリパスと*そのディレクトリ内のすべての(隠されていない)ファイルに拡張されるシェルglobとして呼び出されます。これはls -1、隠しファイル(ピリオドで始まるファイル)を除外する動作と一致します。引数の数は、$#ループに追加しsumて最後に印刷する特別な変数によって提供されます。

配列をサポートするシェルの場合、2番目のアプローチはワイルドカードファイル名を配列に入れてから配列要素の数を数えることです。

$ sum=0
$ for file in $(awk '/Rawdata/ { print $6 }' freeze2-1.out )
  do
    n=("appdata/frozen_files/${file}"/*)
    sum=$((sum + ${#n[@]}))
  done
$ echo "$sum"
6

おすすめ記事