はい

はい

私は現在使用しています

watch head -n 17 *

動作しますが、17日前のすべての行も表示されます。デフォルトでは、現在の方法で表示されている各ファイルの最後の行を表示したいと思います。どうすればいいですか?

はい

たとえば、行数を減らしましょう。 7へ。だから:

サンプルファイル:

1
2
3
4
5
6
7
8

この行は:

watch head -n 7 *

出力

1
2
3
4
5
6
7

私が望む場所:

7

答え1

GNUの使用awk:

watch -x gawk '
  FNR == 17 {nextfile}
  ENDFILE   {if (FNR) printf "%15s[%02d] %s\n", FILENAME, FNR, $0}' ./*

出力は次のとおりです。

        ./file1[17] line17
  ./short-file2[05] line 5 is the last

globは./*呼び出し時に一度だけ拡張されます。watch

あなたのwatch head -n 17 *脆弱性は、拡張が*実際にシェルによってシェルコードとして解釈され、引数をwatch空白に結び付けるため、任意のコマンドインジェクションの脆弱性です。

現在のディレクトリのファイル名がある場合は$(reboot)再起動します。

を使用すると、シェルをスキップしてコマンドを直接実行するように-x指示します。watchまたは、次のことができます。

watch 'exec gawk '\''
  FNR == 17 {nextfile}
  ENDFILE   {if (FNR) printf "%15s[%02d] %s\n", FILENAME, FNR, $0}'\'' ./*'

各反復でglobを拡張するwatchシェルを実行するために使用されます。実際と同じです。を使用すると、必要なシェルを指定できます。たとえば、再帰的なグロービングを実行し、通常のファイルに制限できるより強力なシェルを選択できます。./*watch foo barwatch -x sh -c 'foo bar'watch -xzsh

watch -x zsh -c 'awk '\''...'\'' ./**/*(.)'

そうでない場合gawkでも、次のことができます。

watch '
  for file in ./*; do
    [ -s "$file" ] || continue
    printf "%s: " "$file"
    head -n 17 < "$file" | tail -n 1
  done'

次の出力を提供します。

./file1: line17
./short-file2: line 5 is the last

ただし、これによりファイルごとに複数のコマンドが実行されるため、効率が低下します。

答え2

次の2つの例を組み合わせて、次headのようにします。tail

$ seq 1 80 | head -n 17 | tail -n 1
17

$ seq 1 10 | head -n 17 | tail -n 1
10

したがって、実際の問題を解決するためのコマンドは次のとおりです。

watch 'for f in *; do head -n 17 -- "$f" 2>/dev/null | tail -n 1 ; done'

2>/dev/null*は、読み取り権限のないディレクトリやファイルと一致して隠したいエラーメッセージを生成するため、この部分が必要です。

答え3

find、exec、sedを使用する別の方法

watch find . -type f -name \"*\" -exec sh -c \'\( printf '%-50s ' {} \; sed -n 17p {}\)\' \\\;

関連情報