スクリプト内で特定の単語まで、または検索後のすべてを切り取る方法

スクリプト内で特定の単語まで、または検索後のすべてを切り取る方法

今日の を含むファイルの出力を取得しようとしています"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

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

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

答え1

このbasenameツールはファイル名の前のパスを削除できます。

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

希望する出力が得られます。

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

ファイル名にスペースが含まれている場合、このコマンドは機能しません。この場合、@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

よろしければ./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

答え3

以下を使用できますsed:

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

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

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

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

答え4

これは次のように行うことができます

 echo ${str##*/}

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

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

関連情報