5行以上のファイルを抽出し、同じファイル名を保持します。

5行以上のファイルを抽出し、同じファイル名を保持します。

年次報告書には、エラーを含む複数のファイルがあります。すべてのファイル名に.mvt拡張子があります。すべてのファイルにエラーがあるわけではありません。エラーがある場合、またはエラーがない場合、ファイルには常にヘッダーが5行ずつあることがわかりました。すべてのファイル(300を超えるファイル)を表示する必要はありません。

awk役に立つかどうか疑問に思いましたが、awk 'NR> 5' filename.mvt問題は使用する必要があるということですif else。ファイルをコピーして(cpコマンドを使用して)名前を同じにし、ファイルに5行以上を含める必要があります。

答え1

次のコマンドは、名前が.mvt5行より長く、名前が終わる現在のディレクトリ内または下のすべての一般ファイルを検索します。ファイルごとにファイルのパス名を出力します。

find . -type f -name '*.mvt' -exec sh -c '
    for pathname do
        if [ "$( wc -l <"$pathname" )" -gt 5 ]; then
            printf "%s\n" "$pathname"
        fi
    done' sh {} +

各ファイルをいくつかのディレクトリにコピーします(何をしたいのかわかりません)。実際にこれらのファイルを処理するには、次のことが必要になる場合があります。

mkdir -p possible-error-files || exit 1

find . -type f -name '*.mvt' -exec sh -c '
    for pathname do
        if [ "$( wc -l <"$pathname" )" -gt 5 ]; then
            printf "%s\n" "$pathname"
            cp "$pathname" possible-error-files
        fi
    done' sh {} +

両方のコマンドでファイルの内容を渡してwc -l行数を計算します。

代わりに、awk行数とパス名の出力の両方を実行できます(上記の2番目のコマンドの変更)。

mkdir -p possible-error-files || exit 1

find . -type f -name '*.mvt' -exec sh -c '
    for pathname do
        if awk "BEGIN { err=1 } FNR > 5 { print FILENAME; err=0; exit } END { exit err }" <"$pathname"
        then
            cp "$pathname" possible-error-files
        fi
    done' sh {} +

またはGNUを使用してくださいawk

mkdir -p possible-error-files || exit 1

find . -type f -name '*.mvt' -exec awk '
    FNR > 5 {
        print FILENAME
        system("cp \"" FILENAME "\" possible-error-files")
        nextfile
    }' {} +

答え2

別の解決策は次のとおりです。

for mvt_file in *.mvt; do
    if [ "$(awk 'END {if(NR > 5) print "yes"}' "$mvt_file")" == "yes" ]; then
        cp "$mvt_file" "$mvt_file - copy"
    fi
done

次のようにすることもできます。

for mvt_file in *.mvt; do
    if [ "$(wc -l < "$mvt_file")" -gt 5 ]; then
        cp "$mvt_file" "$mvt_file - copy"
    fi
done

どちらもうまくいきます。

答え3

次のスクリプトを使用して、5行以上のファイルを見つけることができます。

for i in filename1 filename2 filename3 file; do j=`awk '{print NR}' $i| sort -nr| sed -n '1p'`; if [[ $j  > 5 ]]; then echo $i; fi; done| sed '1i below are filenames which having lines more than 5'

関連情報