1行目でパターン検索後のファイル名のみ出力(grep、head利用)

1行目でパターン検索後のファイル名のみ出力(grep、head利用)

だから私は初心者であり、来週プロジェクトの締め切りがあります。#!/bin/bash最初の行に含まれるファイルのファイル名のみを印刷する必要があります。これまで私はこれを試しました

head -n 1 $filename | grep -l "pattern"

ただし、代わりに実行するとファイル名が表示されます。

(standard input)

前述したように、私は初心者であり、これまでは簡単なコマンドに慣れています。だから私がどこを台無しにしているのか、awk

for fis in  find -perm -a+x -name "*.sh" -type f
do
head -n 1 $fis | grep -l "#!/bin/bash"
done

答え1

GNUでは、入力がstdinから来る場合、grepオプションを使用してラベル/ファイル名を設定できます。--label

-execコマンドの置き換えで外部ループを使用する代わりに、この操作を使用してファイル名を繰り返し、コマンドを実行する小さなスクリプトを起動できます。

find -perm -a+x -name "*.sh" -type f -exec sh -c '
  for fis; do
    head -n1 "$fis" | grep --label="$fis" -Fl "#!/bin/bash"
  done
' sh {} +

固定文字列を探しているので、その-Fオプションを追加しました。grep

答え2

私はあなたがawkをブラックリストに投稿したことを知っていますが、助けを求める問題に直面している他の人のために、最初の行に含まれている実行可能ファイルの名前を.sh印刷する非常に効率的な方法は次のとおりです。#!/bin/bash

find . -perm -a+x -name '*.sh' -type f -exec \
    awk 'NR == 1{ if ($0 == "#!/bin/bash") print FILENAME; exit }' {} \;

#!/bin/bashまたは、追加の制限なしで最初の行にファイル名を印刷するには、-permオプション-nameを削除します。

find . -type f -exec awk ...

答え3

find . -perm -a+x -name '*.sh' -type f |
    while IFS= read -r file; do
        test -f "$file" || continue
        if head -n 1 "$file" | grep -qFx '#!/bin/bash'; then
            echo "$file"
        fi
    done

答え4

私はこれがパーティーに非常に遅れていることを知っていますが、私は素晴らしい結果を得るために同じことをしました。

find . -perm -a+x -name "*.sh" -exec \
    bash -c 'grep -q "pattern" < <(head -n 1 "$1")' _ {} \; -printf '%p\n'

-qこのフラグは、標準出力への書き込みを防ぎ、ファイル名(%pfrom)を印刷できるようにすることがわかりますfind -printf

関連情報