web-dev-qa-db-ja.com

特定の単語まで/スクリプトで検索した後にすべてをカットする方法

"ERROR"を含むファイルの出力を今日から取得しようとしています。

これを使用して、必要なファイルを見つけます。

find /home/user/logfilesError/ -maxdepth 1 -type f -name "gandalf_*"\
   -daystart -mtime -1 -exec grep -rl "ERROR" "{}" +

現在の出力(エラーが見つかった場合):

/home/user/logfilesError/gandalf_123.log

しかし、私が望む出力はログファイル名だけです:

gandalf_123.log

情報:パスは頻繁に変わるので、前に文字をカットすることはできません。

ご協力いただきありがとうございます!

3
BlueFox

basenameツールは、ファイル名の前のパスを取り除くことができます。

find /home/user/logfilesError/ -maxdepth 1 -type f -name "gandalf_*"\
-daystart -mtime -1 -exec grep -rl "ERROR" "{}" + | xargs -n 1 basename

目的の出力が得られます。

-n 1は、xargsにbasenameに引数を1つだけ使用するように指示します。したがって、さらに受信すると、引数ごとに1つのbasenameプロセスが生成されます。 basenameは引数として1つのファイル名のみを取るため、これが必要です。

ファイル名にスペースが含まれている場合、このコマンドは機能しません。この場合、@ HaukeLagingによって提案されているように、次を使用します。

find /home/user/logfilesError/ -maxdepth 1 -type f -name "gandalf_*"\
-daystart -mtime -1 -exec grep -rl "ERROR" "{}" + | xargs -n 1 -d \\n basename

ただし、ファイル名に改行が含まれている場合、これは機能しません。

2
lgeorget

./gandalf_123.logで問題がない場合は、

find /home/user/logfilesError/ -maxdepth 1 -type f -name "gandalf_*"\
  -daystart -mtime -1 -execdir grep -rl "ERROR" "{}" +

それ以外の場合は、grep出力をパイプでつなぎます。 sed不要な部分を削除するには:

> echo /home/user/logfilesError/gandalf_123.log |
  sed 's+.*/++'
gandalf_123.log
1
Hauke Laging

sedを使用できます:

... | sed -e 's=.*/=='

これは、/までのものを何も置き換えないように指示します。

cutを使用することもできますが、右から数えることができないため、revと組み合わせる必要があります。

... | rev | cut -d/ -f1 | rev
1
choroba

これはで行うことができます

 echo ${str##*/}

文字列を左から右に最後の「/」までトリミングします

> str=/home/user/logfilesError/gandalf_123.log
> echo ${str##*/}
gandalf_123.log
0
csny