複数のファイルからテキスト文字列を抽出したいのですが、どのようにループを実行できますか?

複数のファイルからテキスト文字列を抽出したいのですが、どのようにループを実行できますか?

私は何千もの.xyzファイルを持っていますが、すべて同じディレクトリに数値データがあります。その中には、最後に「END」というテキスト文字列があります。grep元のファイル名の末尾に何かを追加しながら、「END」が削除され、新しいファイルが生成されるようにコマンドを繰り返す方法がわかりません。

私のファイルのいくつかの最後の数行の例

-1.10949170 55.68890280 -67.60000000
-0.92807500 55.64095280 -89.80000000
-0.95770560 55.66495830 -82.40000000
-0.90995000 55.63676110 -94.00000000
-1.03738890 55.65107220 -70.20000000
END

多くのファイルからENDを削除したいです。

-1.10949170 55.68890280 -67.60000000
-0.92807500 55.64095280 -89.80000000
-0.95770560 55.66495830 -82.40000000
-0.90995000 55.63676110 -94.00000000
-1.03738890 55.65107220 -70.20000000

元のファイル名:survey_2015_xxx.xyz
新しいファイル名: survey_2015_xxx_s.xyz

ベストアンサー1

head負のオフセットをサポートする場合:

for file in *.xyz; do
  if [ "$(tail -n 1 < "$file")" = END ]; then
    head -n -1 < "$file" > "${file%.xyz}_s.xyz"
  fi
done

(そうでない場合head -n -1に置き換えてくださいsed '$d')。

次の方法で効率を向上させることができますksh93

for file in *.xyz; do
  if IFS= read -r last4 < "$file" <#((EOF-4)) <#((here=CUR)) &&
    [ "$last4" = END ]; then
    command /opt/ast/bin/head -c "$here" < "$file" > "${file/%.xyz/_s\0}"
  fi
done

組み込みコマンドのみを使用するためです。

ファイルシステムが参照リンクコピーをサポートしている場合(つまり、変更されるまでデータが繰り返されないファイルをコピーして時間とディスク容量を節約する場合)、ksh93GNUを引き続きcp使用できます。

for file in *.xyz; do
  if IFS= read -r last4 < "$file" <#((EOF-4)) &&
    [ "$last4" = END ]; then
    newfile=${file/%.xyz/_s\0}
    cp --reflink=auto -- "$file" "$newfile" &&
      : 1<>; "$newfile" >#((EOF-4))
  fi
done

つまり、私たちはreflinkのコピーを作成し、最後に4バイトを切り捨てます。

おすすめ記事